* Replication fixes
authorArt Cancro <ajc@citadel.org>
Sat, 16 Oct 1999 22:46:24 +0000 (22:46 +0000)
committerArt Cancro <ajc@citadel.org>
Sat, 16 Oct 1999 22:46:24 +0000 (22:46 +0000)
citadel/msgbase.c
citadel/msgbase.h
citadel/netproc.c
citadel/server.h
citadel/techdoc/hack.txt

index b3fce5047b6d088cee8e3f63ab47deab9c9aaef7..73bc6944e56072462c6fecfefc79ac23ec46f02d 100644 (file)
@@ -32,6 +32,7 @@
 
 #define desired_section ((char *)CtdlGetUserData(SYM_DESIRED_SECTION))
 #define ma ((struct ma_info *)CtdlGetUserData(SYM_MA_INFO))
+#define msg_repl ((struct repl *)CtdlGetUserData(SYM_REPL))
 
 extern struct config config;
 
@@ -63,7 +64,7 @@ char *msgkeys[] = {
        "",
        "",
        "",
-       "zaps"
+       ""
 };
 
 /*
@@ -1206,6 +1207,73 @@ void serialize_message(struct ser_ret *ret,              /* return values */
 
 
 
+/*
+ * Back end for the ReplicationChecks() function
+ */
+void check_repl(long msgnum) {
+       struct CtdlMessage *msg;
+       time_t timestamp;
+
+       msg = NULL;  /* FIX change to get */
+
+
+       if (msg->cm_fields['T'] != NULL) {
+               timestamp = atol(msg->cm_fields['T']);
+               if (timestamp > msg_repl->highest) {
+                       msg_repl->highest = timestamp;  /* newer! */
+                       return;
+               }
+       }
+
+       /* Existing isn't newer?  Then delete the old one(s). */
+       CtdlDeleteMessages(&CC->quickroom.QRname, msgnum, NULL);
+}
+
+
+/*
+ * Check to see if any messages already exist which carry the same Extended ID
+ * as this one.  
+ *
+ * If any are found:
+ * -> With older timestamps: delete them and return 0.  Message will be saved.
+ * -> With newer timestamps: return 1.  Message save will be aborted.
+ */
+int ReplicationChecks(struct CtdlMessage *msg) {
+       struct CtdlMessage *template;
+       int abort_this = 0;
+
+       /* No extended id?  Don't do anything. */
+       if (msg->cm_fields['E'] == NULL) return 0;
+       if (strlen(msg->cm_fields['E']) == 0) return 0;
+
+       CtdlAllocUserData(SYM_REPL, sizeof(struct repl));
+       strcpy(msg_repl->extended_id, msg->cm_fields['E']);
+       msg_repl->highest = (-1L);
+
+       template = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
+       memset(template, 0, sizeof(struct CtdlMessage));
+       template->cm_fields['E'] = strdoop(msg->cm_fields['E']);
+
+       CtdlForEachMessage(MSGS_ALL, 0L, NULL, template, check_repl);
+
+       /* If a newer message exists with the same Extended ID, abort
+        * this save.
+        */
+       if (msg_repl->highest > atol(msg->cm_fields['T']) ) {
+               abort_this = 1;
+               }
+
+       CtdlFreeMessage(template);
+       return(abort_this);
+}
+
+
+
+
+
+
+
+
 /*
  * Save a message to disk
  */
@@ -1295,6 +1363,9 @@ void CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */
        /* Perform "before save" hooks (aborting if any return nonzero) */
        if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return;
 
+       /* If this message has an Extended ID, perform replication checks */
+       if (ReplicationChecks(msg) > 0) return;
+
        /* Network mail - send a copy to the network program. */
        if ((strlen(recipient) > 0) && (mailtype != MES_LOCAL)) {
                sprintf(aaa, "./network/spoolin/netmail.%04lx.%04x.%04x",
index 2cf4c64778d92d2143b5efcb5b746c4dbd6bf2e7..511f440f912844afcd46e413236a61c0ebc2a90e 100644 (file)
@@ -17,6 +17,10 @@ struct ma_info {
 };
 
 
+struct repl {                  /* Info for replication checking */
+       char extended_id[256];
+       time_t highest;
+};
 
 
 int alias (char *name);
index a01ca241e349aa7193b57675734a0be72df6ec3b..9a531dea537a8d82e18fbdbf2bf19d4f70e3129a 100644 (file)
@@ -17,7 +17,6 @@
 #define UUDECODE       "/usr/bin/uudecode"
 
 /* Files used by the networker */
-#define ZAPLIST                "./network/zaplist"
 #define MAILSYSINFO    "./network/mail.sysinfo"
 
 /* Uncomment the DEBUG def to see noisy traces */
@@ -816,88 +815,6 @@ void purge_use_table(GDBM_FILE ut) {
 
 
 
-/*
- * Delete any messages on the zapped list
- */
-void process_zaplist(void) {
-       FILE *zaplist;
-       char curr_rm[ROOMNAMELEN];
-       char buf[256];
-       char room[256];
-       char id[256];
-       char node[256];
-       long localzap = 0L;
-       int numzap = 0;
-
-       zaplist = fopen(ZAPLIST, "r");
-       if (zaplist == NULL) {
-               syslog(LOG_ERR, "cannot open %s: %s\n",
-                       ZAPLIST, strerror(errno));
-               return;
-       }
-
-       strcpy(curr_rm, "_nothing_");
-
-       while (fgets(buf, 256, zaplist) != NULL) {
-               buf[strlen(buf) - 1] = 0;
-
-               extract(room, buf, 0);
-               extract(id, buf, 1);
-               extract(node, buf, 2);
-
-               /* Change rooms if we have to */
-               if (strcasecmp(curr_rm, room)) {
-                       sprintf(buf, "GOTO %s", room);
-                       serv_puts(buf);
-                       serv_gets(buf);
-                       if (buf[0] == '2') {
-                               extract(curr_rm, &buf[4], 0);
-                       } else {
-                               syslog(LOG_ERR, "%s", buf);
-                       }
-               }
-
-               /* And only do the zap if we succeeded */
-               if (!strcasecmp(curr_rm, room)) {
-               
-                       serv_puts("MSGS ALL|0|1");
-                       serv_gets(buf);
-                       if (buf[0]=='1') {
-                               /* This is bogus, flush and go away */
-                               while (serv_gets(buf), strcmp(buf, "000")) ;
-                       }
-                       else if (buf[0]=='8') {
-                               sprintf(buf, "msgn|%s\nnode|%s\n000",
-                                       id, node);
-                               serv_puts(buf);
-                               numzap = 0;
-                               while (serv_gets(buf), strcmp(buf, "000")) {
-                                       localzap = atol(buf);
-                                       ++numzap;
-                               }
-                       }
-       
-                       if (numzap > 0) {
-                               sprintf(buf, "DELE %ld", localzap);
-                               serv_puts(buf);
-                               serv_gets(buf);
-                               if (buf[0] != '2') {
-                                       syslog(LOG_ERR, "%s", buf);
-                               }
-                       }
-                       if (numzap > 1) {
-                               syslog(LOG_ERR, "Multiple messages are <%s@%s>",
-                                       id, node);
-                       }
-       
-               }
-       }
-       fclose(zaplist);
-       unlink(ZAPLIST);
-}
-
-
-
 
 
 /*
@@ -905,7 +822,7 @@ void process_zaplist(void) {
  */
 void inprocess(void)
 {
-       FILE *fp, *message, *testfp, *ls, *duplist, *zaplist;
+       FILE *fp, *message, *testfp, *ls, *duplist;
        static struct minfo minfo;
        struct recentmsg recentmsg;
        char tname[128], aaa[1024], iname[256], sfilename[256], pfilename[256];
@@ -929,9 +846,6 @@ void inprocess(void)
        /* temporary file to contain a log of rejected dups */
        duplist = tmpfile();
 
-       /* Open the zapped-list for appending */
-       zaplist = fopen(ZAPLIST, "a");
-
        /* Let the shell do the dirty work. Get all data from spoolin */
        do {
                sprintf(aaa, "cd %s/network/spoolin; ls", bbs_home_directory);
@@ -1156,20 +1070,6 @@ NXMSG:   /* Seek to the beginning of the next message */
 
                                fclose(message);
                                
-                               /* If this message supersedes an existing one,
-                                * add it to the zap list
-                                */
-                               if (strlen(minfo.Z) > 0) {
-                                       if (strlen(minfo.C) > 0) {
-                                               fprintf(zaplist, "%s", minfo.C);
-                                       } else {
-                                               fprintf(zaplist, "%s", minfo.O);
-                                       }
-                                       extract_token(buf, minfo.Z, 0, '@');
-                                       fprintf(zaplist, "|%s", minfo.Z);
-                                       extract_token(buf, minfo.Z, 1, '@');
-                                       fprintf(zaplist, "|%s\n", minfo.Z);
-                               }
                        }
 
                        unlink(tname);
@@ -1206,12 +1106,6 @@ ENDSTR:                  fclose(fp);
 
        fclose(duplist);
 
-
-       /* Now delete any messages which were zapped (superseded) by
-        * other incoming messages.
-        */
-       fclose(zaplist);
-       process_zaplist();
 }
 
 
index 94c9fce4ff9b5b848865e92d37abf32f35cd9e21..82113952da3b5eec272d77ac60ab4ba2d0ebc861 100644 (file)
@@ -36,6 +36,7 @@ struct CtdlSessData {
 enum {
        SYM_DESIRED_SECTION,            /* Used by the MIME parser */
        SYM_MA_INFO,                    /* Handles multipart/alternative */
+       SYM_REPL,                       /* Used for replication checking */
        SYM_MAX
 };
 
index cad393b1fcb00b4283b76dd021acd2d112794389..52335ddd94b36b965cc7286aa5cd35b7b54debe1 100644 (file)
@@ -83,6 +83,13 @@ B    Phone number    The dialup number of the system this message
                        defined for helping implement C86Net gateways.
 D      Destination     Contains name of the system this message should
                        be sent to, for mail routing (private mail only).
+E      Extended ID     A persistent alphanumeric Message ID used for
+                       network replication.  When a message arrives that
+                       contains an Extended ID, any existing messages which
+                       contain the same Extended ID and are *older* than this
+                       message should be deleted.  If there exist any messages
+                       with the same Extended ID that are *newer*, then this
+                       message should be dropped.
 G      Gateway domain  This field is provided solely for the implementation
                         of C86Net gateways, and holds the C86Net domain of
                         the system this message originated on.  Unless you're
@@ -113,9 +120,6 @@ T   Date/Time       A 32-bit integer containing the date and time of
 U       Subject         Optional.  Developers may choose whether they wish to
                         generate or display subject fields.  Citadel/UX does
                         not generate them, but it does print them when found.
-Z      Zap (supersede) Indicates a message which this message supersedes.
-                       The format is "user@node" and if the specified message
-                       is found, it should be deleted.
   
                        EXAMPLE