From 2248a889099b3b9452b74eeaa7350d4e0ea82d6a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 13 Apr 2002 03:23:08 +0000 Subject: Make our atomic increment code actually do this during its first/second run. The previous code would return the same value for both the initial and second call, only incrementing on later calls. Andrew Bartlett (This used to be commit a4594d9efeca1f67dea57be8323fb4bd986318ce) --- source3/tdb/tdbutil.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index 3e16a03047..bc39082f63 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -219,15 +219,22 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int return -1; if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { - if (tdb_error(tdb) != TDB_ERR_NOEXIST) + /* The lookup failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* but not becouse it didn't exist */ goto err_out; - + } + + /* Start with 'old' value */ val = *oldval; } else { + /* It worked, set return value (oldval) to tdb data */ *oldval = val; - val += change_val; } + + /* Increment value for storage and return next time */ + val += change_val; if (tdb_store_int32(tdb, keystr, val) == -1) goto err_out; @@ -253,15 +260,23 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, char *keystr, uint32 *oldval, ui return False; if (!tdb_fetch_uint32(tdb, keystr, &val)) { - if (tdb_error(tdb) != TDB_ERR_NOEXIST) + /* It failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* and not becouse it didn't exist */ goto err_out; + } + /* Start with 'old' value */ val = *oldval; } else { + /* it worked, set return value (oldval) to tdb data */ *oldval = val; - val += change_val; + } + + /* get a new value to store */ + val += change_val; if (!tdb_store_uint32(tdb, keystr, val)) goto err_out; -- cgit From 07e6ff5fcfe337bb65a7c3a4493a92a7761cf2ed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 14 Apr 2002 09:44:16 +0000 Subject: Partly based on the work by mimir (Rafal Szczesniak ) this patch allows samba to correctly enumerate its trusted domains - by exaimining the keys in the secrets.tdb file. This patch has been tested with both NT4 and rpcclient/wbinfo, and adds some extra functionality to talloc and rpc_parse to allow it to deal with already unicode strings. Finally, this cleans up some const warnings that were in net_rpc.c by pushing another dash of const into the rpc client code. Andrew Bartlett (This used to be commit 0bdd94cb992b40942aaf2e5e0efd2868b4686296) --- source3/tdb/tdbutil.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'source3/tdb') diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index bc39082f63..92a5a9d37f 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include /* these are little tdb utility functions that are meant to make dealing with a tdb database a little less cumbersome in Samba */ @@ -524,3 +525,74 @@ int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, { return tdb_delete(the_tdb, key); } + + + +/** + * Search across the whole tdb for keys that match the given pattern + * return the result as a list of keys + * + * @param tdb pointer to opened tdb file context + * @param pattern searching pattern used by fnmatch(3) functions + * + * @return list of keys found by looking up with given pattern + **/ +TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern) +{ + TDB_DATA key, next; + TDB_LIST_NODE *list = NULL; + TDB_LIST_NODE *rec = NULL; + TDB_LIST_NODE *tmp = NULL; + + for (key = tdb_firstkey(tdb); key.dptr; key = next) { + /* duplicate key string to ensure null-termination */ + char *key_str = (char*) strndup(key.dptr, key.dsize); + if (!key_str) { + DEBUG(0, ("tdb_search_keys: strndup() failed!\n")); + smb_panic("strndup failed!\n"); + } + + DEBUG(18, ("checking %s for match to pattern %s\n", key_str, pattern)); + + next = tdb_nextkey(tdb, key); + + /* do the pattern checking */ + if (fnmatch(pattern, key_str, 0) == 0) { + rec = (TDB_LIST_NODE*) malloc(sizeof(*rec)); + ZERO_STRUCTP(rec); + + rec->node_key = key; + + DLIST_ADD_END(list, rec, tmp); + + DEBUG(18, ("checking %s matched pattern %s\n", key_str, pattern)); + } else { + free(key.dptr); + } + + /* free duplicated key string */ + free(key_str); + } + + return list; + +}; + + +/** + * Free the list returned by tdb_search_keys + * + * @param node list of results found by tdb_search_keys + **/ +void tdb_search_list_free(TDB_LIST_NODE* node) +{ + TDB_LIST_NODE *next_node; + + while (node) { + next_node = node->next; + SAFE_FREE(node); + node = next_node; + }; +}; + + -- cgit From cd58107e6ee337fdacb56ec51711c3164de4aecd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 14 Apr 2002 09:45:09 +0000 Subject: Extra file for the tdb search code (linked list definition). Andrew Bartlett (This used to be commit c3312006009f5b312b285e3e679d01719012f29d) --- source3/tdb/tdbutil.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 source3/tdb/tdbutil.h (limited to 'source3/tdb') diff --git a/source3/tdb/tdbutil.h b/source3/tdb/tdbutil.h new file mode 100644 index 0000000000..01473446a1 --- /dev/null +++ b/source3/tdb/tdbutil.h @@ -0,0 +1,37 @@ +/* + Unix SMB/CIFS implementation. + tdb utility functions + Copyright (C) Andrew Tridgell 1999 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __TDBUTIL_H__ +#define __TDBUTIL_H__ + + +/* single node of a list returned by tdb_search_keys */ +typedef struct keys_node +{ + struct keys_node *prev, *next; + TDB_DATA node_key; +} TDB_LIST_NODE; + + +TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT*, const char*); +void tdb_search_list_free(TDB_LIST_NODE*); + + +#endif /* __TDBUTIL_H__ */ -- cgit From f70836df9e44aaf076447190b310e43258179c23 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Apr 2002 12:27:54 +0000 Subject: ignore a few more files (This used to be commit 1c92fab4050f21b4c5cc962e0b80b5c551b24745) --- source3/tdb/.cvsignore | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/tdb') diff --git a/source3/tdb/.cvsignore b/source3/tdb/.cvsignore index 15ff2846c7..66445fe269 100644 --- a/source3/tdb/.cvsignore +++ b/source3/tdb/.cvsignore @@ -1,5 +1,6 @@ *.po *.po32 +tdbbackup tdbdump tdbtest tdbtool -- cgit From 302b581ddc1f9dcee5c1bcb32da558ae2a7b24c1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Apr 2002 02:08:52 +0000 Subject: First cut at fix for the EINTR problem... More needs to be done I think. Jeremy. (This used to be commit 48475a7a697242b9fd7b1aec24389afb112569c4) --- source3/tdb/tdb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 98caca82a1..e3ba1db0d2 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -169,6 +169,7 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, int rw_type, int lck_type, int probe) { struct flock fl; + int ret; if (tdb->flags & TDB_NOLOCK) return 0; @@ -183,7 +184,12 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, fl.l_len = 1; fl.l_pid = 0; - if (fcntl(tdb->fd,lck_type,&fl) == -1) { + do { + errno = 0; + ret = fcntl(tdb->fd,lck_type,&fl); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { if (!probe) { TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", tdb->fd, offset, rw_type, lck_type)); -- cgit From ca2e14ddc3d753f79319060f3024a0c9b3a57b98 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Apr 2002 21:45:02 +0000 Subject: We cannot set errno=0 in any of the wrapper calls as this breaks UNIX error returns to the client. Jeremy. (This used to be commit 1d66e53a64ec2878293e6d74a852b736ddab8f21) --- source3/tdb/tdb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index e3ba1db0d2..5c0fd436e3 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -185,7 +185,6 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, fl.l_pid = 0; do { - errno = 0; ret = fcntl(tdb->fd,lck_type,&fl); } while (ret == -1 && errno == EINTR); -- cgit From dec3433303cefed83e1a24ba23b79af99cb353e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Apr 2002 18:56:47 +0000 Subject: Merge Herb's idmap endian fix. Jeremy. (This used to be commit 7ddad4061a1b7ed25e4d6471c7a1f8f97a98ed37) --- source3/tdb/tdb.c | 6 ++++++ source3/tdb/tdb.h | 1 + 2 files changed, 7 insertions(+) (limited to 'source3/tdb') diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 5c0fd436e3..c937090de4 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -1471,6 +1471,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, TDB_CONTEXT *tdb; struct stat st; int rev = 0, locked; + unsigned char *vp; + u32 vertest; if (!(tdb = calloc(1, sizeof *tdb))) { /* Can't log this */ @@ -1548,6 +1550,10 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, } rev = (tdb->flags & TDB_CONVERT); } + vp = (unsigned char *)&tdb->header.version; + vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | + (((u32)vp[2]) << 8) | (u32)vp[3]; + tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; if (!rev) tdb->flags &= ~TDB_CONVERT; else { diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h index 54cde10d95..8cc908703f 100644 --- a/source3/tdb/tdb.h +++ b/source3/tdb/tdb.h @@ -38,6 +38,7 @@ extern "C" { #define TDB_NOLOCK 4 /* don't do any locking */ #define TDB_NOMMAP 8 /* don't use mmap */ #define TDB_CONVERT 16 /* convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ #define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) -- cgit From 9d0ff4b777c2bf053b47dab0ae8a5ce007145b7b Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 30 Apr 2002 16:54:14 +0000 Subject: fixed tdbtool from core dumping. But the braces to make Chris happy ! J.F. (This used to be commit d0eae50874ff6ddbf9fca24864e7638efb0936b1) --- source3/tdb/tdbtool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index caa2940141..ba0fb48957 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -368,8 +368,10 @@ static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) dbuf = tdb_fetch(the_tdb, *pkey); if (!dbuf.dptr) terror("fetch failed"); - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(the_tdb, *pkey, dbuf, NULL); + else { + /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ + print_rec(the_tdb, *pkey, dbuf, NULL); + } } static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -- cgit From c33cf24bcd165b23addb0a38f915a92f8256ce9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 May 2002 01:32:12 +0000 Subject: auto-recover from the fairly common case of a non-clean tdb shutdown while deleting a record. This leaves us with a non-free record on the free list. (This used to be commit e99b6a2b91e4022ce0a9a14415df71314b5e013f) --- source3/tdb/tdb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/tdb') diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index c937090de4..14e1d4a24f 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -412,6 +412,16 @@ static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) { if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1; + + if (rec->magic == TDB_MAGIC) { + /* this happens when a app is showdown while deleting a record - we should + not completely fail when this happens */ + TDB_LOG((tdb, 0,"rec_free_read non-free magic at offset=%d - fixing\n", + rec->magic, off)); + rec->magic = TDB_FREE_MAGIC; + tdb_write(tdb, off, rec, sizeof(*rec)); + } + if (rec->magic != TDB_FREE_MAGIC) { TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", rec->magic, off)); -- cgit From 8c64bd92bf3c44599f561abea6abf1841fa88856 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 06:04:14 +0000 Subject: Added tdb_delete_by_string() function. (This used to be commit 0cd3952f408e2fcd2c833b9039dff4392ac16cf7) --- source3/tdb/tdbutil.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/tdb') diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index 92a5a9d37f..1a3a8bb9a5 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -207,6 +207,20 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr) return tdb_fetch(tdb, key); } +/**************************************************************************** + Delete a buffer using a null terminated string key. +****************************************************************************/ + +int tdb_delete_by_string(TDB_CONTEXT *tdb, char *keystr) +{ + TDB_DATA key; + + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + return tdb_delete(tdb, key); +} + /**************************************************************************** Atomic integer change. Returns old value. To create, set initial value in *oldval. ****************************************************************************/ -- cgit From 310e85d7fb3f6d97e6ec7421eb928cad9c8a8838 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jun 2002 03:52:22 +0000 Subject: don't backup to a newer file (This used to be commit ae2f8aa9d0678aa0014d96fc8b1b52f42cba8349) --- source3/tdb/tdbbackup.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdbbackup.c b/source3/tdb/tdbbackup.c index 48c4272d33..f59f98a90f 100644 --- a/source3/tdb/tdbbackup.c +++ b/source3/tdb/tdbbackup.c @@ -224,6 +224,21 @@ static int verify_tdb(const char *fname, const char *bak_name) } +/* + see if one file is newer than another +*/ +static int file_newer(const char *fname1, const char *fname2) +{ + struct stat st1, st2; + if (stat(fname1, &st1) != 0) { + return 0; + } + if (stat(fname2, &st2) != 0) { + return 1; + } + return (st1.st_mtime > st2.st_mtime); +} + static void usage(void) { printf("Usage: tdbbackup [options] \n\n"); @@ -276,7 +291,8 @@ static void usage(void) ret = 1; } } else { - if (backup_tdb(fname, bak_name) != 0) { + if (file_newer(fname, bak_name) && + backup_tdb(fname, bak_name) != 0) { ret = 1; } } -- cgit From 25148a148c1bec680924909722d59d0d47c795ae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Jul 2002 00:06:29 +0000 Subject: *Experimental* new large-scaling printer code. Splits printing.tdb into a separate tdb per printer, but only keeps (currently one) tdb open at a time (although this is easily changed by changing a #define). Needs scalability testing with large numbers of printers now.... Jeremy. (This used to be commit b0909cfa14fc7ef29d2b98b56d52723570da782a) --- source3/tdb/tdb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/tdb') diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 14e1d4a24f..1118ad9c67 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -419,7 +419,8 @@ static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) TDB_LOG((tdb, 0,"rec_free_read non-free magic at offset=%d - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; - tdb_write(tdb, off, rec, sizeof(*rec)); + if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) + return -1; } if (rec->magic != TDB_FREE_MAGIC) { -- cgit