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 /****************************************************************************
28 Lock a chain by string.
29 ****************************************************************************/
31 int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
36 key.dsize = strlen(keyval)+1;
38 return tdb_chainlock(tdb, key);
41 /****************************************************************************
42 Unlock a chain by string.
43 ****************************************************************************/
45 void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
50 key.dsize = strlen(keyval)+1;
52 tdb_chainunlock(tdb, key);
55 /****************************************************************************
56 Fetch a value by a arbitrary blob key, return -1 if not found.
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 ****************************************************************************/
79 int tdb_fetch_int(TDB_CONTEXT *tdb, char *keystr)
81 return tdb_fetch_int_byblob(tdb, keystr, strlen(keystr) + 1);
84 /****************************************************************************
85 Store a value by an arbitary blob key, return 0 on success, -1 on failure.
86 ****************************************************************************/
88 int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v)
94 data.dptr = (void *)&v;
95 data.dsize = sizeof(int);
97 return tdb_store(tdb, key, data, TDB_REPLACE);
100 /****************************************************************************
101 Store a value by string key, return 0 on success, -1 on failure.
102 ****************************************************************************/
104 int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v)
106 return tdb_store_int_byblob(tdb, keystr, strlen(keystr) + 1, v);
109 /****************************************************************************
110 Store a buffer by a null terminated string key. Return 0 on success, -1
112 ****************************************************************************/
114 int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
119 key.dsize = strlen(keystr) + 1;
124 return tdb_store(tdb, key, data, TDB_REPLACE);
127 /****************************************************************************
128 Fetch a buffer using a null terminated string key. Don't forget to call
129 free() on the result dptr.
130 ****************************************************************************/
132 TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
137 key.dsize = strlen(keystr) + 1;
139 return tdb_fetch(tdb, key);
142 /****************************************************************************
143 Atomic integer change. Returns old value. To create, set initial value in *oldval.
144 ****************************************************************************/
146 int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val)
151 if (tdb_lock_bystring(tdb, keystr) == -1)
154 if ((val = tdb_fetch_int(tdb, keystr)) == -1) {
155 if (tdb_error(tdb) != TDB_ERR_NOEXIST)
165 if (tdb_store_int(tdb, keystr, val) == -1)
172 tdb_unlock_bystring(tdb, keystr);
176 /****************************************************************************
177 Useful pair of routines for packing/unpacking data consisting of
178 integers and strings.
179 ****************************************************************************/
181 size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
193 int bufsize0 = bufsize;
198 switch ((c = *fmt++)) {
201 w = (uint16)va_arg(ap, int);
207 d = va_arg(ap, uint32);
213 p = va_arg(ap, void *);
219 s = va_arg(ap,char *);
226 s = va_arg(ap,char *);
234 s = va_arg(ap, char *);
236 if (bufsize >= len) {
242 DEBUG(0,("Unknown tdb_pack format %c in %s\n",
254 DEBUG(18,("tdb_pack(%s, %d) -> %d\n",
255 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
257 return PTR_DIFF(buf, buf0);
260 /****************************************************************************
261 Useful pair of routines for packing/unpacking data consisting of
262 integers and strings.
263 ****************************************************************************/
265 int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
277 int bufsize0 = bufsize;
282 switch ((c=*fmt++)) {
285 w = va_arg(ap, uint16 *);
292 d = va_arg(ap, uint32 *);
299 p = va_arg(ap, void **);
302 *p = (void *)IVAL(buf, 0);
305 s = va_arg(ap,char *);
306 len = strlen(buf) + 1;
307 if (bufsize < len || len > sizeof(pstring))
312 s = va_arg(ap,char *);
313 len = strlen(buf) + 1;
314 if (bufsize < len || len > sizeof(fstring))
319 i = va_arg(ap, int *);
320 b = va_arg(ap, char **);
332 *b = (char *)malloc(*i);
335 memcpy(*b, buf+4, *i);
338 DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
351 DEBUG(18,("tdb_unpack(%s, %d) -> %d\n",
352 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
354 return PTR_DIFF(buf, buf0);
360 /****************************************************************************
361 Log tdb messages via DEBUG().
362 ****************************************************************************/
364 static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
369 va_start(ap, format);
370 vasprintf(&ptr, format, ap);
376 DEBUG(level, ("tdb(%s): %s", tdb->name, ptr));
380 /****************************************************************************
381 Like tdb_open() but also setup a logging function that redirects to
382 the samba DEBUG() system.
383 ****************************************************************************/
385 TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
386 int open_flags, mode_t mode)
391 tdb_flags |= TDB_NOMMAP;
393 tdb = tdb_open(name, hash_size, tdb_flags,
398 tdb_logging_function(tdb, tdb_log);
404 /****************************************************************************
405 Allow tdb_delete to be used as a tdb_traversal_fn.
406 ****************************************************************************/
408 int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
411 return tdb_delete(the_tdb, key);