From: Art Cancro Date: Sat, 16 Oct 1999 22:46:24 +0000 (+0000) Subject: * Replication fixes X-Git-Tag: v7.86~7499 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=bca07fe9d2e256d08e5267834699565652ece116 * Replication fixes --- diff --git a/citadel/msgbase.c b/citadel/msgbase.c index b3fce5047..73bc6944e 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -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", diff --git a/citadel/msgbase.h b/citadel/msgbase.h index 2cf4c6477..511f440f9 100644 --- a/citadel/msgbase.h +++ b/citadel/msgbase.h @@ -17,6 +17,10 @@ struct ma_info { }; +struct repl { /* Info for replication checking */ + char extended_id[256]; + time_t highest; +}; int alias (char *name); diff --git a/citadel/netproc.c b/citadel/netproc.c index a01ca241e..9a531dea5 100644 --- a/citadel/netproc.c +++ b/citadel/netproc.c @@ -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(); } diff --git a/citadel/server.h b/citadel/server.h index 94c9fce4f..82113952d 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -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 }; diff --git a/citadel/techdoc/hack.txt b/citadel/techdoc/hack.txt index cad393b1f..52335ddd9 100644 --- a/citadel/techdoc/hack.txt +++ b/citadel/techdoc/hack.txt @@ -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