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);