#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;
"",
"",
"",
- "zaps"
+ ""
};
/*
+/*
+ * 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
*/
/* 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",
#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 */
-/*
- * 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);
-}
-
-
-
/*
*/
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];
/* 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);
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);
fclose(duplist);
-
- /* Now delete any messages which were zapped (superseded) by
- * other incoming messages.
- */
- fclose(zaplist);
- process_zaplist();
}
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
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