INN commit: trunk/backends (actsync.c)

INN Commit Russ_Allbery at isc.org
Tue Oct 17 00:50:44 UTC 2006


    Date: Monday, October 16, 2006 @ 17:50:43
  Author: jeff
Revision: 7579

Fix bug in which -T flag could not work with the storage API.  Reported
by Mike Brudenell.

The previous implementation required the on-disk representation of the
spool to check for the existence of a top-level hierarchy; this was
fundamentally insufficient at best, and broke completely with the
storage API.

The new implementation uses a hash table to keep track of which
top-level hierarchies exist in the host1 active file, and thus can
detect new hierarchy creation (when -T is used).

Modified:
  trunk/backends/actsync.c

-----------+
 actsync.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 64 insertions(+), 7 deletions(-)

Modified: actsync.c
===================================================================
--- actsync.c	2006-09-11 23:03:12 UTC (rev 7578)
+++ actsync.c	2006-10-17 00:50:43 UTC (rev 7579)
@@ -70,6 +70,7 @@
 
 #include "inn/innconf.h"
 #include "inn/messages.h"
+#include "inn/hashtab.h"
 #include "inn/qio.h"
 #include "libinn.h"
 #include "paths.h"
@@ -322,7 +323,9 @@
                          char *host2);
 static int exec_cmd(int mode, const char *cmd, char *grp, char *type,
                     const char *who);
-static int new_top_hier(char *name);
+static int new_top_hier(char *name, struct hash *existing_hier);
+static const void *string_key(const void *entry);
+static bool string_equal(const void *key, const void *entry);
 
 int
 main(int argc, char *argv[])
@@ -1803,6 +1806,8 @@
     int top_ignore;	/* number of groups ignored because of no top level */
     int restore;	/* host1 groups restored due to -o a1 */
     double host1_same;	/* % of host1 that is the same */
+    struct hash *existing_hier;	/* hash of existing hierarchies for -T */
+    char *p, *q;
     int i;
 
     /* firewall */
@@ -1838,12 +1843,24 @@
      * If -T, ignore new top level groups from host2
      */
     if (no_new_hier) {
+	existing_hier = hash_create(32, hash_string, string_key,
+		string_equal, free);
+	for (i=0; i < grplen; ++i) {
+	    if (grp[i].hostid == HOSTID2)
+		continue;
+	    p = xstrdup(grp[i].name);
+	    q = strchr(p, '.');
+	    if (q != NULL)
+		*q = '\0';
+	    if (!hash_insert(existing_hier, p, p))
+		free(p);
+	}
 	top_ignore = 0;
 	for (i=0; i < grplen; ++i) {
 	    /* look at new newsgroups */
 	    if (grp[i].hostid == HOSTID2 &&
 		grp[i].output != 0 &&
-		new_top_hier(grp[i].name)) {
+		new_top_hier(grp[i].name, existing_hier)) {
 		 /* no top level ignore this new group */
 		 grp[i].ignore |= CHECK_HIER;
 		 grp[i].output = 0;
@@ -1853,6 +1870,7 @@
 		 ++top_ignore;
 	    }
 	}
+	hash_free(existing_hier);
 	if (D_SUMMARY)
             warn("STATUS: ignored %d new newsgroups due to new hierarchy",
                  top_ignore);
@@ -2688,17 +2706,15 @@
  *
  * given:
  *	name	name of newsgroup to check
+ *	existing_hier	hash table of existing hierarchies
  *
  * returns:
  *	false	hierarchy already exists
  *	true	hierarchy does not exist, name represents a new hierarchy
- *
- * NOTE: This function assumes that we are at the top of the news spool.
  */
 static int
-new_top_hier(char *name)
+new_top_hier(char *name, struct hash *existing_hier)
 {
-    struct stat	statbuf;	/* stat of the hierarchy */
     int result;			/* return result */
     char *dot;
 
@@ -2713,7 +2729,8 @@
     /*
      * determine if we can find this top level hierarchy directory
      */
-    result = !(stat(name, &statbuf) >= 0 && S_ISDIR(statbuf.st_mode));
+    result = (hash_lookup(existing_hier, name) == NULL);
+
     /* restore name */
     if (dot != NULL) {
 	*dot = '.';
@@ -2724,3 +2741,43 @@
      */
     return result;
 }
+
+/*
+ * string_key - identity function, for use with hashtab library
+ *
+ * Returns its only argument.
+ *
+ * given:
+ *	entry	void* pointer representing a string
+ *
+ * returns:
+ *	the same void* pointer
+ */
+static const void *
+string_key(const void *entry)
+{
+    return entry;
+}
+
+/*
+ * string_equal - string comparison function, for use with hashtab library
+ *
+ * Compares two strings.
+ *
+ * given:
+ *	key	void* pointer representing a hash table key
+ *	entry	void* pointer representing a hash table entry
+ *
+ * returns:
+ *	0	arguments are not equal
+ *	1	arguments are equal
+ */
+static bool
+string_equal(const void *key, const void *entry)
+{
+    const char *p, *q;
+
+    p = key;
+    q = entry;
+    return !strcmp(p, q);
+}



More information about the inn-committers mailing list