]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Replication fixes
[citadel.git] / citadel / msgbase.c
index 341b587cf75bb5a20087e5b360350f4cbd4cf099..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;
 
@@ -56,14 +57,14 @@ char *msgkeys[] = {
        "path",
        "",
        "rcpt",
-       ""
+       "",
        "time",
        "subj",
        "",
        "",
        "",
        "",
-       "zaps"
+       ""
 };
 
 /*
@@ -730,6 +731,7 @@ void output_message(char *msgid, int mode, int headers_only)
        time_t xtime;
        CIT_UBYTE ch;
        char allkeys[256];
+       char display_name[256];
 
        struct CtdlMessage *TheMessage = NULL;
 
@@ -819,32 +821,41 @@ void output_message(char *msgid, int mode, int headers_only)
 
        if ((mode == MT_CITADEL) || (mode == MT_MIME)) {
 
+               strcpy(display_name, "<unknown>");
                if (TheMessage->cm_fields['A']) {
                        strcpy(buf, TheMessage->cm_fields['A']);
                        PerformUserHooks(buf, (-1L), EVT_OUTPUTMSG);
                        if (TheMessage->cm_anon_type == MES_ANON)
-                               cprintf("from=****");
+                               strcpy(display_name, "****");
                        else if (TheMessage->cm_anon_type == MES_AN2)
-                               cprintf("from=anonymous");
+                               strcpy(display_name, "anonymous");
                        else
-                               cprintf("from=%s", buf);
+                               strcpy(display_name, buf);
                        if ((is_room_aide())
                            && ((TheMessage->cm_anon_type == MES_ANON)
                             || (TheMessage->cm_anon_type == MES_AN2))) {
-                               cprintf(" [%s]", buf);
+                               sprintf(&display_name[strlen(display_name)],
+                                       " [%s]", buf);
                        }
-                       cprintf("\n");
                }
 
                strcpy(allkeys, FORDER);
                for (i=0; i<strlen(allkeys); ++i) {
                        k = (int) allkeys[i];
-                       if ((k != 'A') && (k != 'M')) {
-                               if (TheMessage->cm_fields[k] != NULL)
-                                       cprintf("%s=%s\n",
-                                               msgkeys[k],
-                                               TheMessage->cm_fields[k]
+                       if (k != 'M') {
+                               if (TheMessage->cm_fields[k] != NULL) {
+                                       if (k == 'A') {
+                                               cprintf("%s=%s\n",
+                                                       msgkeys[k],
+                                                       display_name);
+                                       }
+                                       else {
+                                               cprintf("%s=%s\n",
+                                                       msgkeys[k],
+                                                       TheMessage->cm_fields[k]
                                        );
+                                       }
+                               }
                        }
                }
 
@@ -1196,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
  */
@@ -1285,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",
@@ -1770,6 +1851,7 @@ void cmd_ent3(char *entargs)
                msg->cm_fields[which_field] = strdoop(tempbuf);
        }
 
+       msg->cm_flags = CM_SKIP_HOOKS;
        CtdlSaveMsg(msg, recp, "", e, 0);
        CtdlFreeMessage(msg);
        phree(tempbuf);
@@ -1864,7 +1946,8 @@ void cmd_dele(char *delstr)
        getuser(&CC->usersupp, CC->curr_user);
        if ((CC->usersupp.axlevel < 6)
            && (CC->usersupp.usernum != CC->quickroom.QRroomaide)
-           && ((CC->quickroom.QRflags & QR_MAILBOX) == 0)) {
+           && ((CC->quickroom.QRflags & QR_MAILBOX) == 0)
+           && (!(CC->internal_pgm))) {
                cprintf("%d Higher access required.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
                return;