2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* these are little tdb utility functions that are meant to make
25 dealing with a tdb database a little less cumbersome in Samba */
27 /* lock a chain by string */
28 int tdb_lock_bystring(TDB_CONTEXT
*tdb
, char *keyval
)
33 key
.dsize
= strlen(keyval
)+1;
35 return tdb_chainlock(tdb
, key
);
38 /* unlock a chain by string */
39 void tdb_unlock_bystring(TDB_CONTEXT
*tdb
, char *keyval
)
44 key
.dsize
= strlen(keyval
)+1;
46 tdb_chainunlock(tdb
, key
);
49 /* fetch a value by a arbitrary blob key, return -1 if not found */
50 int tdb_fetch_int_byblob(TDB_CONTEXT
*tdb
, char *keyval
, size_t len
)
57 data
= tdb_fetch(tdb
, key
);
58 if (!data
.dptr
|| data
.dsize
!= sizeof(int)) return -1;
60 memcpy(&ret
, data
.dptr
, sizeof(int));
65 /* fetch a value by string key, return -1 if not found */
66 int tdb_fetch_int(TDB_CONTEXT
*tdb
, char *keystr
)
68 return tdb_fetch_int_byblob(tdb
, keystr
, strlen(keystr
) + 1);
71 /* store a value by an arbitary blob key, return 0 on success, -1 on failure */
72 int tdb_store_int_byblob(TDB_CONTEXT
*tdb
, char *keystr
, size_t len
, int v
)
78 data
.dptr
= (void *)&v
;
79 data
.dsize
= sizeof(int);
81 return tdb_store(tdb
, key
, data
, TDB_REPLACE
);
84 /* store a value by string key, return 0 on success, -1 on failure */
85 int tdb_store_int(TDB_CONTEXT
*tdb
, char *keystr
, int v
)
87 return tdb_store_int_byblob(tdb
, keystr
, strlen(keystr
) + 1, v
);
90 /* Store a buffer by a null terminated string key. Return 0 on success, -1
92 int tdb_store_by_string(TDB_CONTEXT
*tdb
, char *keystr
, void *buffer
, int len
)
97 key
.dsize
= strlen(keystr
) + 1;
102 return tdb_store(tdb
, key
, data
, TDB_REPLACE
);
105 /* Fetch a buffer using a null terminated string key. Don't forget to call
106 free() on the result dptr. */
108 TDB_DATA
tdb_fetch_by_string(TDB_CONTEXT
*tdb
, char *keystr
)
113 key
.dsize
= strlen(keystr
) + 1;
115 return tdb_fetch(tdb
, key
);
118 /* Atomic integer change. Returns old value. To create, set initial value in *oldval. */
120 int tdb_change_int_atomic(TDB_CONTEXT
*tdb
, char *keystr
, int *oldval
, int change_val
)
125 if (tdb_lock_bystring(tdb
, keystr
) == -1)
128 if ((val
= tdb_fetch_int(tdb
, keystr
)) == -1) {
129 if (tdb_error(tdb
) != TDB_ERR_NOEXIST
)
139 if (tdb_store_int(tdb
, keystr
, val
) == -1)
146 tdb_unlock_bystring(tdb
, keystr
);
150 /* useful pair of routines for packing/unpacking data consisting of
151 integers and strings */
152 size_t tdb_pack(char *buf
, int bufsize
, char *fmt
, ...)
164 int bufsize0
= bufsize
;
169 switch ((c
= *fmt
++)) {
172 w
= (uint16
)va_arg(ap
, int);
173 if (bufsize
>= len
) {
179 d
= va_arg(ap
, uint32
);
180 if (bufsize
>= len
) {
186 p
= va_arg(ap
, void *);
188 if (bufsize
>= len
) {
193 s
= va_arg(ap
,char *);
196 if (bufsize
>= len
) {
201 s
= va_arg(ap
,char *);
204 if (bufsize
>= len
) {
210 s
= va_arg(ap
, char *);
212 if (bufsize
>= len
) {
218 DEBUG(0,("Unknown tdb_pack format %c in %s\n",
230 DEBUG(8,("tdb_pack(%s, %d) -> %d\n",
231 fmt0
, bufsize0
, (int)PTR_DIFF(buf
, buf0
)));
233 return PTR_DIFF(buf
, buf0
);
238 /* useful pair of routines for packing/unpacking data consisting of
239 integers and strings */
241 int tdb_unpack(char *buf
, int bufsize
, char *fmt
, ...)
253 int bufsize0
= bufsize
;
258 switch ((c
=*fmt
++)) {
261 w
= va_arg(ap
, uint16
*);
262 if (bufsize
< len
) goto no_space
;
267 d
= va_arg(ap
, uint32
*);
268 if (bufsize
< len
) goto no_space
;
273 p
= va_arg(ap
, void **);
274 if (bufsize
< len
) goto no_space
;
275 *p
= (void *)IVAL(buf
, 0);
278 s
= va_arg(ap
,char *);
279 len
= strlen(buf
) + 1;
280 if (bufsize
< len
|| len
> sizeof(pstring
)) goto no_space
;
284 s
= va_arg(ap
,char *);
285 len
= strlen(buf
) + 1;
286 if (bufsize
< len
|| len
> sizeof(fstring
)) goto no_space
;
290 i
= va_arg(ap
, int *);
291 b
= va_arg(ap
, char **);
293 if (bufsize
< len
) goto no_space
;
300 if (bufsize
< len
) goto no_space
;
301 *b
= (char *)malloc(*i
);
302 if (! *b
) goto no_space
;
303 memcpy(*b
, buf
+4, *i
);
306 DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
319 DEBUG(8,("tdb_unpack(%s, %d) -> %d\n",
320 fmt0
, bufsize0
, (int)PTR_DIFF(buf
, buf0
)));
322 return PTR_DIFF(buf
, buf0
);
328 /****************************************************************************
329 log tdb messages via DEBUG()
330 ****************************************************************************/
331 static void tdb_log(TDB_CONTEXT
*tdb
, int level
, const char *format
, ...)
336 va_start(ap
, format
);
337 vasprintf(&ptr
, format
, ap
);
340 if (!ptr
|| !*ptr
) return;
342 DEBUG(level
, ("tdb(%s): %s", tdb
->name
, ptr
));
348 /* like tdb_open() but also setup a logging function that redirects to
349 the samba DEBUG() system */
350 TDB_CONTEXT
*tdb_open_log(char *name
, int hash_size
, int tdb_flags
,
351 int open_flags
, mode_t mode
)
353 TDB_CONTEXT
*tdb
= tdb_open(name
, hash_size
, tdb_flags
,
355 if (!tdb
) return NULL
;
357 tdb_logging_function(tdb
, tdb_log
);