diff options
-rw-r--r-- | source3/Makefile.in | 4 | ||||
-rw-r--r-- | source3/include/includes.h | 1 | ||||
-rw-r--r-- | source3/lib/tdb/common/tdbback.c | 227 | ||||
-rw-r--r-- | source3/lib/tdb/include/tdbback.h | 23 | ||||
-rw-r--r-- | source3/lib/tdb/tools/tdbbackup.c | 192 |
5 files changed, 171 insertions, 276 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index b200ede14b..527c1912f6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -200,7 +200,7 @@ TDBBASE_OBJ = lib/tdb/common/tdb.o lib/tdb/common/dump.o lib/tdb/common/error.o lib/tdb/common/open.o lib/tdb/common/transaction.o \ lib/tdb/common/traverse.o -TDB_OBJ = $(TDBBASE_OBJ) lib/util_tdb.o lib/tdb/common/tdbback.o +TDB_OBJ = $(TDBBASE_OBJ) lib/util_tdb.o SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@ @@ -883,7 +883,7 @@ POPT_OBJ=popt/findme.o popt/popt.o popt/poptconfig.o \ INIPARSER_OBJ = iniparser/src/iniparser.o iniparser/src/dictionary.o \ iniparser/src/strlib.o -TDBBACKUP_OBJ = lib/tdb/tools/tdbbackup.o lib/tdb/common/tdbback.o $(LIBREPLACE_OBJ) \ +TDBBACKUP_OBJ = lib/tdb/tools/tdbbackup.o $(LIBREPLACE_OBJ) \ $(TDBBASE_OBJ) $(SOCKET_WRAPPER_OBJ) TDBTOOL_OBJ = lib/tdb/tools/tdbtool.o $(TDBBASE_OBJ) $(LIBREPLACE_OBJ) \ diff --git a/source3/include/includes.h b/source3/include/includes.h index 53f6ab8b58..90d2723251 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -635,7 +635,6 @@ typedef int BOOL; #include "dlinklist.h" #include "tdb.h" #include "util_tdb.h" -#include "tdbback.h" #include "lib/talloc/talloc.h" /* And a little extension. Abort on type mismatch */ diff --git a/source3/lib/tdb/common/tdbback.c b/source3/lib/tdb/common/tdbback.c deleted file mode 100644 index 28de85c29f..0000000000 --- a/source3/lib/tdb/common/tdbback.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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. -*/ - -#ifdef STANDALONE -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <sys/mman.h> - -#include <sys/stat.h> -#include <sys/time.h> -#include <ctype.h> -#include <signal.h> - -#else -#include "includes.h" - -#ifdef malloc -#undef malloc -#endif - -#ifdef realloc -#undef realloc -#endif - -#ifdef calloc -#undef calloc -#endif - -#endif - -#include "tdb.h" - -static int failed; - -char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = (char *)malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - snprintf(ret, len, "%s%s", name, suffix); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb)); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -int backup_tdb(const char *old_name, const char *new_name, int hash_size) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - free(tmp_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); - if (!tdb) { - printf("Failed to open %s\n", old_name); - free(tmp_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, - hash_size ? hash_size : tdb_hash_size(tdb), - TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, - st.st_mode & 0777); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the old tdb */ - if (tdb_lockall(tdb) != 0) { - fprintf(stderr,"Failed to lock %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, 0); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* make sure the new tdb has reached stable storage */ - fsync(tdb_fd(tdb_new)); - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - unlink(new_name); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - - - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, 0); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} diff --git a/source3/lib/tdb/include/tdbback.h b/source3/lib/tdb/include/tdbback.h deleted file mode 100644 index 69d3bb6f91..0000000000 --- a/source3/lib/tdb/include/tdbback.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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. -*/ - -char *add_suffix(const char *name, const char *suffix); -int backup_tdb(const char *old_name, const char *new_name, int hash_size); -int verify_tdb(const char *fname, const char *bak_name); diff --git a/source3/lib/tdb/tools/tdbbackup.c b/source3/lib/tdb/tools/tdbbackup.c index 4ae5a4f921..2e728d46aa 100644 --- a/source3/lib/tdb/tools/tdbbackup.c +++ b/source3/lib/tdb/tools/tdbbackup.c @@ -41,36 +41,182 @@ */ -#ifdef STANDALONE -#if HAVE_CONFIG_H -#include <config.h> +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "tdb.h" + +#ifdef HAVE_GETOPT_H +#include <getopt.h> #endif -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ctype.h> -#include <signal.h> +static int failed; + +static char *add_suffix(const char *name, const char *suffix) +{ + char *ret; + int len = strlen(name) + strlen(suffix) + 1; + ret = (char *)malloc(len); + if (!ret) { + fprintf(stderr,"Out of memory!\n"); + exit(1); + } + snprintf(ret, len, "%s%s", name, suffix); + return ret; +} -#else +static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; -#include "includes.h" + if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { + fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb)); + failed = 1; + return 1; + } + return 0; +} -#endif -#include "tdb.h" -#include "tdbback.h" +static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + return 0; +} -extern int optind; -extern char *optarg; +/* + carefully backup a tdb, validating the contents and + only doing the backup if its OK + this function is also used for restore +*/ +static int backup_tdb(const char *old_name, const char *new_name, int hash_size) +{ + TDB_CONTEXT *tdb; + TDB_CONTEXT *tdb_new; + char *tmp_name; + struct stat st; + int count1, count2; + + tmp_name = add_suffix(new_name, ".tmp"); + + /* stat the old tdb to find its permissions */ + if (stat(old_name, &st) != 0) { + perror(old_name); + free(tmp_name); + return 1; + } + + /* open the old tdb */ + tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); + if (!tdb) { + printf("Failed to open %s\n", old_name); + free(tmp_name); + return 1; + } + + /* create the new tdb */ + unlink(tmp_name); + tdb_new = tdb_open(tmp_name, + hash_size ? hash_size : tdb_hash_size(tdb), + TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, + st.st_mode & 0777); + if (!tdb_new) { + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* lock the old tdb */ + if (tdb_lockall(tdb) != 0) { + fprintf(stderr,"Failed to lock %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + failed = 0; + + /* traverse and copy */ + count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); + if (count1 < 0 || failed) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* close the old tdb */ + tdb_close(tdb); + + /* close the new tdb and re-open read-only */ + tdb_close(tdb_new); + tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); + if (!tdb_new) { + fprintf(stderr,"failed to reopen %s\n", tmp_name); + unlink(tmp_name); + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* traverse the new tdb to confirm */ + count2 = tdb_traverse(tdb_new, test_fn, 0); + if (count2 != count1) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* make sure the new tdb has reached stable storage */ + fsync(tdb_fd(tdb_new)); + + /* close the new tdb and rename it to .bak */ + tdb_close(tdb_new); + unlink(new_name); + if (rename(tmp_name, new_name) != 0) { + perror(new_name); + free(tmp_name); + return 1; + } + + free(tmp_name); + + return 0; +} + +/* + verify a tdb and if it is corrupt then restore from *.bak +*/ +static int verify_tdb(const char *fname, const char *bak_name) +{ + TDB_CONTEXT *tdb; + int count = -1; + + /* open the tdb */ + tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + + /* traverse the tdb, then close it */ + if (tdb) { + count = tdb_traverse(tdb, test_fn, NULL); + tdb_close(tdb); + } + + /* count is < 0 means an error */ + if (count < 0) { + printf("restoring %s\n", fname); + return backup_tdb(bak_name, fname, 0); + } + + printf("%s : %d records\n", fname, count); + + return 0; +} /* see if one file is newer than another |