2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* these are little tdb utility functions that are meant to make
24 dealing with a tdb database a little less cumbersome in Samba */
26 /****************************************************************************
27 Lock a chain by string.
28 ****************************************************************************/
30 int tdb_lock_bystring(TDB_CONTEXT
*tdb
, char *keyval
)
35 key
.dsize
= strlen(keyval
)+1;
37 return tdb_chainlock(tdb
, key
);
40 /****************************************************************************
41 Unlock a chain by string.
42 ****************************************************************************/
44 void tdb_unlock_bystring(TDB_CONTEXT
*tdb
, char *keyval
)
49 key
.dsize
= strlen(keyval
)+1;
51 tdb_chainunlock(tdb
, key
);
54 /****************************************************************************
55 Fetch a int32 value by a arbitrary blob key, return -1 if not found.
56 Output is int32 in native byte order.
57 ****************************************************************************/
59 int32
tdb_fetch_int32_byblob(TDB_CONTEXT
*tdb
, char *keyval
, size_t len
)
66 data
= tdb_fetch(tdb
, key
);
67 if (!data
.dptr
|| data
.dsize
!= sizeof(int32
))
70 ret
= IVAL(data
.dptr
,0);
75 /****************************************************************************
76 Fetch a int32 value by string key, return -1 if not found.
77 Output is int32 in native byte order.
78 ****************************************************************************/
80 int32
tdb_fetch_int32(TDB_CONTEXT
*tdb
, char *keystr
)
82 return tdb_fetch_int32_byblob(tdb
, keystr
, strlen(keystr
) + 1);
85 /****************************************************************************
86 Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure.
87 Input is int32 in native byte order. Output in tdb is in little-endian.
88 ****************************************************************************/
90 int tdb_store_int32_byblob(TDB_CONTEXT
*tdb
, char *keystr
, size_t len
, int32 v
)
98 data
.dptr
= (void *)&v_store
;
99 data
.dsize
= sizeof(int32
);
101 return tdb_store(tdb
, key
, data
, TDB_REPLACE
);
104 /****************************************************************************
105 Store a int32 value by string key, return 0 on success, -1 on failure.
106 Input is int32 in native byte order. Output in tdb is in little-endian.
107 ****************************************************************************/
109 int tdb_store_int32(TDB_CONTEXT
*tdb
, char *keystr
, int32 v
)
111 return tdb_store_int32_byblob(tdb
, keystr
, strlen(keystr
) + 1, v
);
114 /****************************************************************************
115 Fetch a uint32 value by a arbitrary blob key, return -1 if not found.
116 Output is uint32 in native byte order.
117 ****************************************************************************/
119 BOOL
tdb_fetch_uint32_byblob(TDB_CONTEXT
*tdb
, char *keyval
, size_t len
, uint32
*value
)
125 data
= tdb_fetch(tdb
, key
);
126 if (!data
.dptr
|| data
.dsize
!= sizeof(uint32
))
129 *value
= IVAL(data
.dptr
,0);
130 SAFE_FREE(data
.dptr
);
134 /****************************************************************************
135 Fetch a uint32 value by string key, return -1 if not found.
136 Output is uint32 in native byte order.
137 ****************************************************************************/
139 BOOL
tdb_fetch_uint32(TDB_CONTEXT
*tdb
, char *keystr
, uint32
*value
)
141 return tdb_fetch_uint32_byblob(tdb
, keystr
, strlen(keystr
) + 1, value
);
144 /****************************************************************************
145 Store a uint32 value by an arbitary blob key, return 0 on success, -1 on failure.
146 Input is uint32 in native byte order. Output in tdb is in little-endian.
147 ****************************************************************************/
149 BOOL
tdb_store_uint32_byblob(TDB_CONTEXT
*tdb
, char *keystr
, size_t len
, uint32 value
)
157 SIVAL(&v_store
, 0, value
);
158 data
.dptr
= (void *)&v_store
;
159 data
.dsize
= sizeof(uint32
);
161 if (tdb_store(tdb
, key
, data
, TDB_REPLACE
) == -1)
167 /****************************************************************************
168 Store a uint32 value by string key, return 0 on success, -1 on failure.
169 Input is uint32 in native byte order. Output in tdb is in little-endian.
170 ****************************************************************************/
172 BOOL
tdb_store_uint32(TDB_CONTEXT
*tdb
, char *keystr
, uint32 value
)
174 return tdb_store_uint32_byblob(tdb
, keystr
, strlen(keystr
) + 1, value
);
176 /****************************************************************************
177 Store a buffer by a null terminated string key. Return 0 on success, -1
179 ****************************************************************************/
181 int tdb_store_by_string(TDB_CONTEXT
*tdb
, char *keystr
, void *buffer
, int len
)
186 key
.dsize
= strlen(keystr
) + 1;
191 return tdb_store(tdb
, key
, data
, TDB_REPLACE
);
194 /****************************************************************************
195 Fetch a buffer using a null terminated string key. Don't forget to call
196 free() on the result dptr.
197 ****************************************************************************/
199 TDB_DATA
tdb_fetch_by_string(TDB_CONTEXT
*tdb
, char *keystr
)
204 key
.dsize
= strlen(keystr
) + 1;
206 return tdb_fetch(tdb
, key
);
209 /****************************************************************************
210 Atomic integer change. Returns old value. To create, set initial value in *oldval.
211 ****************************************************************************/
213 int32
tdb_change_int32_atomic(TDB_CONTEXT
*tdb
, char *keystr
, int32
*oldval
, int32 change_val
)
218 if (tdb_lock_bystring(tdb
, keystr
) == -1)
221 if ((val
= tdb_fetch_int32(tdb
, keystr
)) == -1) {
222 /* The lookup failed */
223 if (tdb_error(tdb
) != TDB_ERR_NOEXIST
) {
224 /* but not becouse it didn't exist */
228 /* Start with 'old' value */
232 /* It worked, set return value (oldval) to tdb data */
236 /* Increment value for storage and return next time */
239 if (tdb_store_int32(tdb
, keystr
, val
) == -1)
246 tdb_unlock_bystring(tdb
, keystr
);
250 /****************************************************************************
251 Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval.
252 ****************************************************************************/
254 BOOL
tdb_change_uint32_atomic(TDB_CONTEXT
*tdb
, char *keystr
, uint32
*oldval
, uint32 change_val
)
259 if (tdb_lock_bystring(tdb
, keystr
) == -1)
262 if (!tdb_fetch_uint32(tdb
, keystr
, &val
)) {
264 if (tdb_error(tdb
) != TDB_ERR_NOEXIST
) {
265 /* and not becouse it didn't exist */
269 /* Start with 'old' value */
273 /* it worked, set return value (oldval) to tdb data */
278 /* get a new value to store */
281 if (!tdb_store_uint32(tdb
, keystr
, val
))
288 tdb_unlock_bystring(tdb
, keystr
);
292 /****************************************************************************
293 Useful pair of routines for packing/unpacking data consisting of
294 integers and strings.
295 ****************************************************************************/
297 size_t tdb_pack(char *buf
, int bufsize
, char *fmt
, ...)
309 int bufsize0
= bufsize
;
314 switch ((c
= *fmt
++)) {
317 w
= (uint16
)va_arg(ap
, int);
323 d
= va_arg(ap
, uint32
);
329 p
= va_arg(ap
, void *);
335 s
= va_arg(ap
,char *);
342 s
= va_arg(ap
,char *);
350 s
= va_arg(ap
, char *);
352 if (bufsize
>= len
) {
358 DEBUG(0,("Unknown tdb_pack format %c in %s\n",
370 DEBUG(18,("tdb_pack(%s, %d) -> %d\n",
371 fmt0
, bufsize0
, (int)PTR_DIFF(buf
, buf0
)));
373 return PTR_DIFF(buf
, buf0
);
376 /****************************************************************************
377 Useful pair of routines for packing/unpacking data consisting of
378 integers and strings.
379 ****************************************************************************/
381 int tdb_unpack(char *buf
, int bufsize
, char *fmt
, ...)
393 int bufsize0
= bufsize
;
398 switch ((c
=*fmt
++)) {
401 w
= va_arg(ap
, uint16
*);
408 d
= va_arg(ap
, uint32
*);
415 p
= va_arg(ap
, void **);
418 *p
= (void *)IVAL(buf
, 0);
421 s
= va_arg(ap
,char *);
422 len
= strlen(buf
) + 1;
423 if (bufsize
< len
|| len
> sizeof(pstring
))
428 s
= va_arg(ap
,char *);
429 len
= strlen(buf
) + 1;
430 if (bufsize
< len
|| len
> sizeof(fstring
))
435 i
= va_arg(ap
, int *);
436 b
= va_arg(ap
, char **);
448 *b
= (char *)malloc(*i
);
451 memcpy(*b
, buf
+4, *i
);
454 DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
467 DEBUG(18,("tdb_unpack(%s, %d) -> %d\n",
468 fmt0
, bufsize0
, (int)PTR_DIFF(buf
, buf0
)));
470 return PTR_DIFF(buf
, buf0
);
476 /****************************************************************************
477 Log tdb messages via DEBUG().
478 ****************************************************************************/
480 static void tdb_log(TDB_CONTEXT
*tdb
, int level
, const char *format
, ...)
485 va_start(ap
, format
);
486 vasprintf(&ptr
, format
, ap
);
492 DEBUG(level
, ("tdb(%s): %s", tdb
->name
? tdb
->name
: "unknown", ptr
));
496 /****************************************************************************
497 Like tdb_open() but also setup a logging function that redirects to
498 the samba DEBUG() system.
499 ****************************************************************************/
501 TDB_CONTEXT
*tdb_open_log(const char *name
, int hash_size
, int tdb_flags
,
502 int open_flags
, mode_t mode
)
507 tdb_flags
|= TDB_NOMMAP
;
509 tdb
= tdb_open_ex(name
, hash_size
, tdb_flags
,
510 open_flags
, mode
, tdb_log
);
518 /****************************************************************************
519 Allow tdb_delete to be used as a tdb_traversal_fn.
520 ****************************************************************************/
522 int tdb_traverse_delete_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
, TDB_DATA dbuf
,
525 return tdb_delete(the_tdb
, key
);