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 value by a arbitrary blob key, return -1 if not found.
56 JRA. DEPRECATED ! Use tdb_fetch_int32_byblob instead.
57 ****************************************************************************/
59 int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
66 data = tdb_fetch(tdb, key);
67 if (!data.dptr || data.dsize != sizeof(int))
70 memcpy(&ret, data.dptr, sizeof(int));
75 /****************************************************************************
76 Fetch a value by string key, return -1 if not found.
77 JRA. DEPRECATED ! Use tdb_fetch_int32 instead.
78 ****************************************************************************/
80 int tdb_fetch_int(TDB_CONTEXT *tdb, char *keystr)
82 return tdb_fetch_int_byblob(tdb, keystr, strlen(keystr) + 1);
85 /****************************************************************************
86 Store a value by an arbitary blob key, return 0 on success, -1 on failure.
87 JRA. DEPRECATED ! Use tdb_store_int32_byblob instead.
88 ****************************************************************************/
90 int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v)
96 data.dptr = (void *)&v;
97 data.dsize = sizeof(int);
99 return tdb_store(tdb, key, data, TDB_REPLACE);
102 /****************************************************************************
103 Store a value by string key, return 0 on success, -1 on failure.
104 JRA. DEPRECATED ! Use tdb_store_int32 instead.
105 ****************************************************************************/
107 int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v)
109 return tdb_store_int_byblob(tdb, keystr, strlen(keystr) + 1, v);
112 /****************************************************************************
113 Fetch a int32 value by a arbitrary blob key, return -1 if not found.
114 Output is int32 in native byte order.
115 ****************************************************************************/
117 int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
124 data = tdb_fetch(tdb, key);
125 if (!data.dptr || data.dsize != sizeof(int32))
128 ret = IVAL(data.dptr,0);
129 SAFE_FREE(data.dptr);
133 /****************************************************************************
134 Fetch a int32 value by string key, return -1 if not found.
135 Output is int32 in native byte order.
136 ****************************************************************************/
138 int32 tdb_fetch_int32(TDB_CONTEXT *tdb, char *keystr)
140 return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1);
143 /****************************************************************************
144 Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure.
145 Input is int32 in native byte order. Output in tdb is in little-endian.
146 ****************************************************************************/
148 int tdb_store_int32_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int32 v)
156 data.dptr = (void *)&v_store;
157 data.dsize = sizeof(int32);
159 return tdb_store(tdb, key, data, TDB_REPLACE);
162 /****************************************************************************
163 Store a int32 value by string key, return 0 on success, -1 on failure.
164 Input is int32 in native byte order. Output in tdb is in little-endian.
165 ****************************************************************************/
167 int tdb_store_int32(TDB_CONTEXT *tdb, char *keystr, int32 v)
169 return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v);
172 /****************************************************************************
173 Store a buffer by a null terminated string key. Return 0 on success, -1
175 ****************************************************************************/
177 int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
182 key.dsize = strlen(keystr) + 1;
187 return tdb_store(tdb, key, data, TDB_REPLACE);
190 /****************************************************************************
191 Fetch a buffer using a null terminated string key. Don't forget to call
192 free() on the result dptr.
193 ****************************************************************************/
195 TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
200 key.dsize = strlen(keystr) + 1;
202 return tdb_fetch(tdb, key);
205 /****************************************************************************
206 Atomic integer change. Returns old value. To create, set initial value in *oldval.
207 Deprecated. Use int32 version. JRA.
208 ****************************************************************************/
210 int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val)
215 if (tdb_lock_bystring(tdb, keystr) == -1)
218 if ((val = tdb_fetch_int(tdb, keystr)) == -1) {
219 if (tdb_error(tdb) != TDB_ERR_NOEXIST)
229 if (tdb_store_int(tdb, keystr, val) == -1)
236 tdb_unlock_bystring(tdb, keystr);
240 /****************************************************************************
241 Atomic integer change. Returns old value. To create, set initial value in *oldval.
242 ****************************************************************************/
244 int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int32 change_val)
249 if (tdb_lock_bystring(tdb, keystr) == -1)
252 if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
253 if (tdb_error(tdb) != TDB_ERR_NOEXIST)
263 if (tdb_store_int32(tdb, keystr, val) == -1)
270 tdb_unlock_bystring(tdb, keystr);
274 /****************************************************************************
275 Useful pair of routines for packing/unpacking data consisting of
276 integers and strings.
277 ****************************************************************************/
279 size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
291 int bufsize0 = bufsize;
296 switch ((c = *fmt++)) {
299 w = (uint16)va_arg(ap, int);
305 d = va_arg(ap, uint32);
311 p = va_arg(ap, void *);
317 s = va_arg(ap,char *);
324 s = va_arg(ap,char *);
332 s = va_arg(ap, char *);
334 if (bufsize >= len) {
340 DEBUG(0,("Unknown tdb_pack format %c in %s\n",
352 DEBUG(18,("tdb_pack(%s, %d) -> %d\n",
353 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
355 return PTR_DIFF(buf, buf0);
358 /****************************************************************************
359 Useful pair of routines for packing/unpacking data consisting of
360 integers and strings.
361 ****************************************************************************/
363 int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
375 int bufsize0 = bufsize;
380 switch ((c=*fmt++)) {
383 w = va_arg(ap, uint16 *);
390 d = va_arg(ap, uint32 *);
397 p = va_arg(ap, void **);
400 *p = (void *)IVAL(buf, 0);
403 s = va_arg(ap,char *);
404 len = strlen(buf) + 1;
405 if (bufsize < len || len > sizeof(pstring))
410 s = va_arg(ap,char *);
411 len = strlen(buf) + 1;
412 if (bufsize < len || len > sizeof(fstring))
417 i = va_arg(ap, int *);
418 b = va_arg(ap, char **);
430 *b = (char *)malloc(*i);
433 memcpy(*b, buf+4, *i);
436 DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
449 DEBUG(18,("tdb_unpack(%s, %d) -> %d\n",
450 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
452 return PTR_DIFF(buf, buf0);
458 /****************************************************************************
459 Log tdb messages via DEBUG().
460 ****************************************************************************/
462 static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
467 va_start(ap, format);
468 vasprintf(&ptr, format, ap);
474 DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unknown", ptr));
478 /****************************************************************************
479 Like tdb_open() but also setup a logging function that redirects to
480 the samba DEBUG() system.
481 ****************************************************************************/
483 TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags,
484 int open_flags, mode_t mode)
489 tdb_flags |= TDB_NOMMAP;
491 tdb = tdb_open_ex(name, hash_size, tdb_flags,
492 open_flags, mode, tdb_log);
500 /****************************************************************************
501 Allow tdb_delete to be used as a tdb_traversal_fn.
502 ****************************************************************************/
504 int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
507 return tdb_delete(the_tdb, key);