PATCH (revised) [was: Bogoutil error ...]

David Relson relson at osagesoftware.com
Wed Mar 9 02:31:50 CET 2005


On Tue, 8 Mar 2005 20:05:17 -0500
Clint Adams wrote:

> > or you can try this patch; save the body of this email, unpack
> 
> The patch doesn't apply cleanly to 0.94.0, and there is a problem with
> number of arguments to dsm_recover_open().

Further, there's a file/directory confusion issue ...

At datastore_db.c:943 is:

    dbe = dsm->dsm_recover_open(directory);

However at datastore_db_trad.c:43 is:

  static DB_ENV *bft_recover_open (const char *db_file);

Changing datastore_db.c to 

   dbe = dsm->dsm_recover_open(db_file);

corrects the problem.

Updated patch (with all datastore*.c changes) attached.

David
-------------- next part --------------
diff -u -r --exclude-from=diff.excl 0940/src/datastore.c cvs/src/datastore.c
--- 0940/src/datastore.c	2005-02-24 21:20:27.000000000 -0500
+++ cvs/src/datastore.c	2005-03-08 19:57:41.224079320 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore.c,v 1.65 2005/02/25 00:57:51 m-a Exp $ */
+/* $Id: datastore.c,v 1.66 2005/03/09 00:42:15 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -471,6 +471,6 @@
     return dbe_purgelogs(directory);
 }
 
-int ds_verify(const char *file) {
-    return db_verify(file);
+int ds_verify(const char *directory, const char *file) {
+    return db_verify(directory, file);
 }
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db.c cvs/src/datastore_db.c
--- 0940/src/datastore_db.c	2005-02-27 19:09:01.000000000 -0500
+++ cvs/src/datastore_db.c	2005-03-08 20:26:57.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db.c,v 1.182 2005/02/28 00:09:01 relson Exp $ */
+/* $Id: datastore_db.c,v 1.186 2005/03/09 01:26:57 relson Exp $ */
 
 /*****************************************************************************
 
@@ -266,21 +266,21 @@
 
     dbe_t *env;
 
-    if (NULL == realpath(directory, norm_dir)) {
+    if (realpath(directory, norm_dir) == NULL) {
 	    print_error(__FILE__, __LINE__,
 		    "error: cannot normalize path \"%s\": %s",
 		    directory, strerror(errno));
 	    exit(EX_ERROR);
     }
 
-    if (NULL == realpath(bogohome, norm_home)) {
+    if (realpath(bogohome, norm_home) == NULL) {
 	    print_error(__FILE__, __LINE__,
 		    "error: cannot normalize path \"%s\": %s",
 		    bogohome, strerror(errno));
 	    exit(EX_ERROR);
     }
 
-    if (0 != strcmp(norm_dir, norm_home))
+    if (strcmp(norm_dir, norm_home) != 0)
     {
 	fprintf(stderr,
 		"ERROR: only one database _environment_ (directory) can be used at a time.\n"
@@ -927,7 +927,7 @@
     return db_strerror(e);
 }
 
-ex_t db_verify(const char *db_file)
+ex_t db_verify(const char *directory, const char *db_file)
 {
     DB_ENV *dbe = NULL;
     DB *db;
@@ -938,11 +938,23 @@
 	return EX_ERROR;
     }
 
-    dbe = dsm->dsm_recover_open(db_file, &db);
+    dsm_init(directory, db_file);
+
+    dbe = dsm->dsm_recover_open(db_file);
     if (dbe == NULL) {
 	exit(EX_ERROR);
     }
 
+    e = db_create(&db, NULL, 0); /* need not use environment here,
+				    DB->verify() does not lock anyways,
+				    we must hold the global lock instead */
+
+    if (e != 0) {
+	print_error(__FILE__, __LINE__, "error creating DB handle: %s",
+		db_strerror(e));
+	exit(EX_ERROR);
+    }
+
     e = db->verify(db, db_file, NULL, NULL, 0);
     if (e) {
 	print_error(__FILE__, __LINE__, "database %s does not verify: %s",
@@ -950,7 +962,7 @@
 	exit(EX_ERROR);
     }
 
-    e = dsm->dsm_common_close(dbe, db_file);
+    e = dsm->dsm_common_close(dbe, directory);
 
     if (e == 0 && verbose)
 	printf("%s OK.\n", db_file);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db.h cvs/src/datastore_db.h
--- 0940/src/datastore_db.h	2005-02-27 14:37:12.000000000 -0500
+++ cvs/src/datastore_db.h	2005-03-08 19:57:41.340061688 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db.h,v 1.32 2005/02/19 02:01:24 m-a Exp $ */
+/* $Id: datastore_db.h,v 1.33 2005/03/09 00:42:15 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -102,7 +102,7 @@
 ex_t dbe_purgelogs(const char *directory);
 
 /** Check if \a databasefile is a valid database. */
-ex_t db_verify(const char *databasefile);
+ex_t db_verify(const char *directory, const char *databasefile);
 
 /** Returns true if the database is byteswapped. */
 bool db_is_swapped(void *vhandle);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_private.h cvs/src/datastore_db_private.h
--- 0940/src/datastore_db_private.h	2005-02-27 19:00:21.000000000 -0500
+++ cvs/src/datastore_db_private.h	2005-03-07 23:09:24.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_private.h,v 1.5 2005/02/27 19:46:23 relson Exp $ */
+/* $Id: datastore_db_private.h,v 1.6 2005/03/08 00:39:56 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -46,7 +46,7 @@
 typedef const char *dsm_pc_pc	(const char *db_file);
 typedef ex_t	dsm_x_pnvpc	(DB_ENV *dbe, const char *db_file);
 typedef dbe_t  *dsm_pbe_pc	(const char *directory);
-typedef DB_ENV *dsm_pnv_pcpb	(const char *db_file, DB **dbp);
+typedef DB_ENV *dsm_pnv_pc	(const char *db_file);
 typedef DB_ENV *dsm_pnv_pbe	(dbe_t *env);
 
 typedef struct {
@@ -60,7 +60,7 @@
     dsm_v_pbe	 *dsm_cleanup_lite;
     dsm_pnv_pbe	 *dsm_get_env_dbe;
     dsm_pc_pc	 *dsm_database_name;
-    dsm_pnv_pcpb *dsm_recover_open;
+    dsm_pnv_pc	 *dsm_recover_open;
     dsm_i_v	 *dsm_auto_commit_flags;
     dsm_i_i	 *dsm_get_rmw_flag;
     dsm_i_pvi	 *dsm_lock;
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_trad.c cvs/src/datastore_db_trad.c
--- 0940/src/datastore_db_trad.c	2005-02-17 23:28:37.000000000 -0500
+++ cvs/src/datastore_db_trad.c	2005-03-07 23:09:24.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_trad.c,v 1.4 2005/02/18 04:19:02 m-a Exp $ */
+/* $Id: datastore_db_trad.c,v 1.5 2005/03/08 00:39:56 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -40,7 +40,7 @@
 /* private -- used in datastore_db_*.c */
 static DB_ENV	  *bft_get_env_dbe	(dbe_t *env);
 static const char *bft_database_name	(const char *db_file);
-static DB_ENV	  *bft_recover_open	(const char *db_file, DB **dbp);
+static DB_ENV	  *bft_recover_open	(const char *db_file);
 static int	   bft_auto_commit_flags(void);
 static int	   bft_get_rmw_flag	(int open_mode);
 static int	   bft_lock		(void *handle, int open_mode);
@@ -133,9 +133,8 @@
     return 0;
 }
 
-DB_ENV *bft_recover_open(const char *db_file, DB **dbp)
+DB_ENV *bft_recover_open(const char *db_file)
 {
-    int e;
     int fd;
 
     fd = open(db_file, O_RDWR);
@@ -153,13 +152,6 @@
 	exit(EX_ERROR);
     }
 
-    if ((e = db_create (dbp, NULL, 0)) != 0) {
-	print_error(__FILE__, __LINE__, "db_create, err: %s",
-		    db_strerror(e));
-	close(fd);
-	exit(EX_ERROR);
-    }
-
     return NULL;
 }
 
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_trans.c cvs/src/datastore_db_trans.c
--- 0940/src/datastore_db_trans.c	2005-03-05 16:08:11.000000000 -0500
+++ cvs/src/datastore_db_trans.c	2005-03-08 19:57:41.344061080 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_trans.c,v 1.7 2005/03/02 23:22:03 m-a Exp $ */
+/* $Id: datastore_db_trans.c,v 1.12 2005/03/08 10:26:31 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -60,7 +60,7 @@
 /* private -- used in datastore_db_*.c */
 static DB_ENV	  *dbx_get_env_dbe	(dbe_t *env);
 static const char *dbx_database_name	(const char *db_file);
-static DB_ENV	  *dbx_recover_open	(const char *db_file, DB **dbp);
+static DB_ENV	  *dbx_recover_open	(const char *db_file);
 static int	   dbx_auto_commit_flags(void);
 static int	   dbx_get_rmw_flag	(int open_mode);
 static int	   dbx_lock		(void *handle, int open_mode);
@@ -162,6 +162,36 @@
     return flag;
 }
 
+/** print user-readable diagnostics and instructions after DB_ENV->open
+ * failed. */
+static void diag_dbeopen(
+	/** DB_ENV->open() flags value  */ u_int32_t flags,
+	/** env directory tried to open */ const char *directory)
+{
+    if (flags & DB_RECOVER) {
+	fprintf(stderr,
+		"\n"
+		"### Standard recovery failed. ###\n"
+		"\n"
+		"Please check section 3.3 in bogofilter's README.db file\n"
+		"for help.\n");
+	/* ask that the user runs catastrophic recovery */
+    } else if (flags & DB_RECOVER_FATAL) {
+	fprintf(stderr,
+		"\n"
+		"### Catastrophic recovery failed. ###\n"
+		"\n"
+		"Please check the README.db file that came with bogofilter for hints,\n"
+		"section 3.3, or remove all __db.*, log.* and *.db files in \"%s\"\n"
+		"and start from scratch.\n", directory);
+	/* catastrophic recovery failed */
+    } else {
+	fprintf(stderr, "To recover, run: bogoutil -v --db-recover \"%s\"\n",
+		directory);
+    }
+}
+
+/** run recovery, open environment and keep the exclusive lock */
 static DB_ENV *dbe_recover_open(const char *directory, uint32_t flags)
 {
     const uint32_t local_flags = flags | DB_CREATE;
@@ -189,38 +219,20 @@
 
     e = dbe->open(dbe, directory,
 		  dbenv_defflags | local_flags | DB_RECOVER, DS_MODE);
-    if (e == DB_RUNRECOVERY) {
-	/* that didn't work, try harder */
-	if (DEBUG_DATABASE(0))
-	    fprintf(dbgout, "running catastrophic data base recovery\n");
-	e = dbe->open(dbe, directory,
-		      dbenv_defflags | local_flags | DB_RECOVER_FATAL, DS_MODE);
-    }
     if (e) {
 	print_error(__FILE__, __LINE__, "Cannot recover environment \"%s\": %s",
 		directory, db_strerror(e));
+	if (e == DB_RUNRECOVERY)
+	    diag_dbeopen(flags, directory);
 	exit(EX_ERROR);
     }
 
     return dbe;
 }
 
-static DB_ENV *dbx_recover_open(const char *dir, DB **dbp)
+static DB_ENV *dbx_recover_open(const char *dir)
 {
-    int e;
-    DB_ENV *dbe;
-
-    dbe = dbe_recover_open(dir, 0); /* this sets an exclusive lock */
-    e = db_create(dbp, NULL, 0);    /* do not use environment here, verify
-				       does not lock by itself, we hold the
-				       global lock instead! */
-    if (e != 0) {
-	print_error(__FILE__, __LINE__, "error creating DB handle: %s",
-		    db_strerror(e));
-	return NULL;
-    }
-
-    return dbe;
+    return dbe_recover_open(dir, 0);
 }
 
 static int dbx_begin(void *vhandle)
@@ -536,27 +548,7 @@
 	print_error(__FILE__, __LINE__, "DB_ENV->open, err: %s", db_strerror(ret));
 	switch (ret) {
 	    case DB_RUNRECOVERY:
-		if (flags & DB_RECOVER) {
-		    fprintf(stderr,
-			    "\n"
-			    "### Standard recovery failed. ###\n"
-			    "\n"
-			    "Please check section 3.3 in bogofilter's README.db file\n"
-			    "for help.\n");
-		    /* ask that the user runs catastrophic recovery */
-		} else if (flags & DB_RECOVER_FATAL) {
-		    fprintf(stderr,
-			    "\n"
-			    "### Catastrophic recovery failed. ###\n"
-			    "\n"
-			    "Please check the README.db file that came with bogofilter for hints,\n"
-			    "section 3.3, or remove all __db.*, log.* and *.db files in \"%s\"\n"
-			    "and start from scratch.\n", directory);
-		    /* catastrophic recovery failed */
-		} else {
-		    fprintf(stderr, "To recover, run: bogoutil -v --db-recover \"%s\"\n",
-			    directory);
-		}
+		diag_dbeopen(flags, directory);
 		break;
 	    case EINVAL:
 		fprintf(stderr, "\n"
@@ -648,7 +640,6 @@
     if (!(force || needs_recovery()))
 	return EX_OK;
 
-retry:
     if (DEBUG_DATABASE(0))
         fprintf(dbgout, "running %s data base recovery\n",
 	    catastrophic ? "catastrophic" : "regular");
@@ -656,20 +647,13 @@
 		    db_max_locks, db_max_objects,
 		    catastrophic ? DB_RECOVER_FATAL : DB_RECOVER);
     if (env == NULL) {
-	if(!catastrophic) {
-	    catastrophic = true;
-	    goto retry;
-	}
-	goto rec_fail;
+	exit(EX_ERROR);
     }
 
     clear_lockfile();
     dbx_cleanup_lite(env);
 
     return EX_OK;
-
-rec_fail:
-    exit(EX_ERROR);
 }
 
 static ex_t dbx_common_close(DB_ENV *dbe, const char *directory)
@@ -679,6 +663,9 @@
     if (db_log_autoremove)
 	dbe_env_purgelogs(dbe);
 
+    if (DEBUG_DATABASE(0))
+	fprintf(dbgout, "closing environment\n");
+
     e = dbe->close(dbe, 0);
     if (e != 0) {
 	print_error(__FILE__, __LINE__, "Error closing environment \"%s\": %s",
@@ -744,9 +731,6 @@
 
     dbe_env_purgelogs(dbe);
 
-    if (DEBUG_DATABASE(0))
-	fprintf(dbgout, "closing environment\n");
-
     return dbx_common_close(dbe, directory);
 }
 
@@ -902,7 +886,11 @@
 	return P_ERROR;
     }
 
+#if DB_AT_LEAST(3,2)
     r = dbe->open(dbe, directory, DB_JOINENV, DS_MODE);
+#else
+    r = ENOENT;
+#endif
     if (r == ENOENT) {
 	struct stat st;
 	int w;
@@ -910,11 +898,12 @@
 	struct dirent *de;
 	DIR *d;
 
-	/* no environment found by JOINENV */
+	/* no environment found by JOINENV, but clean up handle */
 	dbe->close(dbe, 0);
 
-	/* retry globbing for log.* files - needed for instance after
-	 * bogoutil --db-remove DIR */
+	/* retry, looking for log\.[0-9]{10} files - needed for instance
+	 * after bogoutil --db-remove DIR or when DB_JOINENV is
+	 * unsupported */
 	d = opendir(directory);
 	if (!d) {
 	    print_error(__FILE__, __LINE__, "cannot open directory %s: %s",
diff -u -r --exclude-from=diff.excl 0940/src/datastore.h cvs/src/datastore.h
--- 0940/src/datastore.h	2005-02-18 21:32:01.000000000 -0500
+++ cvs/src/datastore.h	2005-03-08 19:57:41.334062600 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore.h,v 1.43 2005/02/19 02:01:24 m-a Exp $ */
+/* $Id: datastore.h,v 1.44 2005/03/09 00:42:15 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -251,7 +251,7 @@
 extern int ds_remove(const char *directory);
 
 /** Verify given database */
-extern int ds_verify(const char *file);
+extern int ds_verify(const char *directory, const char *file);
 
 /** Remove inactive log files in given directory, \return EX_OK. */
 extern int ds_purgelogs(const char *directory);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_qdbm.c cvs/src/datastore_qdbm.c
--- 0940/src/datastore_qdbm.c	2005-02-04 23:33:19.000000000 -0500
+++ cvs/src/datastore_qdbm.c	2005-03-08 19:57:41.355059408 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_qdbm.c,v 1.43 2005/01/14 04:43:44 relson Exp $ */
+/* $Id: datastore_qdbm.c,v 1.44 2005/03/09 00:42:16 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -324,7 +324,8 @@
     return dperrmsg(e);
 }
 
-ex_t db_verify(const char *f) {
+ex_t db_verify(const char *d, const char *f) {
     (void)f;
+    (void)d;
     return EX_OK;
 }
diff -u -r --exclude-from=diff.excl 0940/src/datastore_sqlite.c cvs/src/datastore_sqlite.c
--- 0940/src/datastore_sqlite.c	2005-02-27 18:08:22.000000000 -0500
+++ cvs/src/datastore_sqlite.c	2005-03-08 19:57:41.372056824 -0500
@@ -40,10 +40,10 @@
 DUMMYVVP(dbe_cleanup)
 DUMMYVVP(db_flush)
 DUMMYVPVP(db_get_env)
-DUMMYICP(db_verify)
 DUMMYICP(dbe_purgelogs)
 DUMMYICP(dbe_remove)
 void *dbe_init(const char *d1, const char *d2) { (void)d1; (void)d2; return (void *)~0; }
+ex_t db_verify(const char *d1, const char *d2) { (void)d1; (void)d2; return EX_OK; }
 /** dummy function, Sqlite recovers automatically. */
 ex_t dbe_recover(const char *d1, bool d2, bool d3) { (void)d1; d2=d3; return EX_ERROR; }
 
@@ -270,10 +270,13 @@
     /* check if byteswapped */
     {
 	u_int32_t t;
-	k.data = strdup(ENDIAN32);
+	int ee;
+	k.data = xstrdup(ENDIAN32);
 	k.leng = strlen(k.data);
 
-	switch(db_get_dbvalue(dbh, &k, &v)) {
+	ee = db_get_dbvalue(dbh, &k, &v);
+	free(k.data);
+	switch(ee) {
 	    case 0: /* found endian marker token, read it */
 		if (v.leng < 4)
 		    goto barf;
diff -u -r --exclude-from=diff.excl 0940/src/datastore_tdb.c cvs/src/datastore_tdb.c
--- 0940/src/datastore_tdb.c	2005-02-04 23:33:19.000000000 -0500
+++ cvs/src/datastore_tdb.c	2005-03-08 19:57:41.374056520 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_tdb.c,v 1.43 2005/01/16 17:39:17 relson Exp $ */
+/* $Id: datastore_tdb.c,v 1.44 2005/03/09 00:42:16 m-a Exp $ */
 
 /*****************************************************************************
 
@@ -348,7 +348,8 @@
 	return "Invalid error code";
 }
 
-ex_t db_verify(const char *f) {
+ex_t db_verify(const char *d, const char *f) {
     (void)f;
+    (void)d;
     return EX_OK;
 }
-------------- next part --------------
_______________________________________________
Bogofilter mailing list
Bogofilter at bogofilter.org
http://www.bogofilter.org/mailman/listinfo/bogofilter


More information about the bogofilter mailing list