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 JRA. DEPRECATED ! Use tdb_fetch_int32_byblob instead.
58 ****************************************************************************/
60 int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
67 data = tdb_fetch(tdb, key);
68 if (!data.dptr || data.dsize != sizeof(int))
71 memcpy(&ret, data.dptr, sizeof(int));
76 /****************************************************************************
77 Fetch a value by string key, return -1 if not found.
78 JRA. DEPRECATED ! Use tdb_fetch_int32 instead.
79 ****************************************************************************/
81 int tdb_fetch_int(TDB_CONTEXT *tdb, char *keystr)
83 return tdb_fetch_int_byblob(tdb, keystr, strlen(keystr) + 1);
86 /****************************************************************************
87 Store a value by an arbitary blob key, return 0 on success, -1 on failure.
88 JRA. DEPRECATED ! Use tdb_store_int32_byblob instead.
89 ****************************************************************************/
91 int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v)
97 data.dptr = (void *)&v;
98 data.dsize = sizeof(int);
100 return tdb_store(tdb, key, data, TDB_REPLACE);
103 /****************************************************************************
104 Store a value by string key, return 0 on success, -1 on failure.
105 JRA. DEPRECATED ! Use tdb_store_int32 instead.
106 ****************************************************************************/
108 int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v)
110 return tdb_store_int_byblob(tdb, keystr, strlen(keystr) + 1, v);
113 /****************************************************************************
114 Fetch a int32 value by a arbitrary blob key, return -1 if not found.
115 Output is int32 in native byte order.
116 ****************************************************************************/
118 int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
125 data = tdb_fetch(tdb, key);
126 if (!data.dptr || data.dsize != sizeof(int32))
129 ret = IVAL(data.dptr,0);
130 SAFE_FREE(data.dptr);
134 /****************************************************************************
135 Fetch a int32 value by string key, return -1 if not found.
136 Output is int32 in native byte order.
137 ****************************************************************************/
139 int32 tdb_fetch_int32(TDB_CONTEXT *tdb, char *keystr)
141 return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1);
144 /****************************************************************************
145 Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure.
146 Input is int32 in native byte order. Output in tdb is in little-endian.
147 ****************************************************************************/
149 int tdb_store_int32_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int32 v)
157 data.dptr = (void *)&v_store;
158 data.dsize = sizeof(int32);
160 return tdb_store(tdb, key, data, TDB_REPLACE);
163 /****************************************************************************
164 Store a int32 value by string key, return 0 on success, -1 on failure.
165 Input is int32 in native byte order. Output in tdb is in little-endian.
166 ****************************************************************************/
168 int tdb_store_int32(TDB_CONTEXT *tdb, char *keystr, int32 v)
170 return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v);
173 /****************************************************************************
174 Store a buffer by a null terminated string key. Return 0 on success, -1
176 ****************************************************************************/
178 int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
183 key.dsize = strlen(keystr) + 1;
188 return tdb_store(tdb, key, data, TDB_REPLACE);
191 /****************************************************************************
192 Fetch a buffer using a null terminated string key. Don't forget to call
193 free() on the result dptr.
194 ****************************************************************************/
196 TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
201 key.dsize = strlen(keystr) + 1;
203 return tdb_fetch(tdb, key);
206 /****************************************************************************
207 Atomic integer change. Returns old value. To create, set initial value in *oldval.
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 Useful pair of routines for packing/unpacking data consisting of
242 integers and strings.
243 ****************************************************************************/
245 size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
257 int bufsize0 = bufsize;
262 switch ((c = *fmt++)) {
265 w = (uint16)va_arg(ap, int);
271 d = va_arg(ap, uint32);
277 p = va_arg(ap, void *);
283 s = va_arg(ap,char *);
290 s = va_arg(ap,char *);
298 s = va_arg(ap, char *);
300 if (bufsize >= len) {
306 DEBUG(0,("Unknown tdb_pack format %c in %s\n",
318 DEBUG(18,("tdb_pack(%s, %d) -> %d\n",
319 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
321 return PTR_DIFF(buf, buf0);
324 /****************************************************************************
325 Useful pair of routines for packing/unpacking data consisting of
326 integers and strings.
327 ****************************************************************************/
329 int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
341 int bufsize0 = bufsize;
346 switch ((c=*fmt++)) {
349 w = va_arg(ap, uint16 *);
356 d = va_arg(ap, uint32 *);
363 p = va_arg(ap, void **);
366 *p = (void *)IVAL(buf, 0);
369 s = va_arg(ap,char *);
370 len = strlen(buf) + 1;
371 if (bufsize < len || len > sizeof(pstring))
376 s = va_arg(ap,char *);
377 len = strlen(buf) + 1;
378 if (bufsize < len || len > sizeof(fstring))
383 i = va_arg(ap, int *);
384 b = va_arg(ap, char **);
396 *b = (char *)malloc(*i);
399 memcpy(*b, buf+4, *i);
402 DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
415 DEBUG(18,("tdb_unpack(%s, %d) -> %d\n",
416 fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
418 return PTR_DIFF(buf, buf0);
424 /****************************************************************************
425 Log tdb messages via DEBUG().
426 ****************************************************************************/
428 static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
433 va_start(ap, format);
434 vasprintf(&ptr, format, ap);
440 DEBUG(level, ("tdb(%s): %s", tdb->name, ptr));
444 /****************************************************************************
445 Like tdb_open() but also setup a logging function that redirects to
446 the samba DEBUG() system.
447 ****************************************************************************/
449 TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
450 int open_flags, mode_t mode)
455 tdb_flags |= TDB_NOMMAP;
457 tdb = tdb_open(name, hash_size, tdb_flags,
462 tdb_logging_function(tdb, tdb_log);
468 /****************************************************************************
469 Allow tdb_delete to be used as a tdb_traversal_fn.
470 ****************************************************************************/
472 int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
475 return tdb_delete(the_tdb, key);