]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Finished removing all the "dynamic session data" stuff in order to
[citadel.git] / citadel / msgbase.c
index 2c34eaa76956a535e5e32c6745919dd467d3060f..ed2973be3620d96dc9ebd9750adb2c1c06092bd3 100644 (file)
 #include "genstamp.h"
 #include "internet_addressing.h"
 
-#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;
 long config_msgnum;
 
@@ -569,7 +565,7 @@ void cmd_msgs(char *cmdbuf)
                template = (struct CtdlMessage *)
                        malloc(sizeof(struct CtdlMessage));
                memset(template, 0, sizeof(struct CtdlMessage));
-               while(client_gets(buf), strcmp(buf,"000")) {
+               while(client_getln(buf, sizeof buf), strcmp(buf,"000")) {
                        extract(tfield, buf, 0);
                        extract(tvalue, buf, 1);
                        for (i='A'; i<='Z'; ++i) if (msgkeys[i]!=NULL) {
@@ -763,7 +759,7 @@ void mime_download(char *name, char *filename, char *partnum, char *disp,
                return;
 
        /* ...or if this is not the desired section */
-       if (strcasecmp(desired_section, partnum))
+       if (strcasecmp(CC->download_desired_section, partnum))
                return;
 
        CC->download_fp = tmpfile();
@@ -916,12 +912,15 @@ void fixed_output_pre(char *name, char *filename, char *partnum, char *disp,
                void *content, char *cbtype, size_t length, char *encoding,
                void *cbuserdata)
 {
-               lprintf(CTDL_DEBUG, "fixed_output_pre() type=<%s>\n", cbtype);  
-               if (!strcasecmp(cbtype, "multipart/alternative")) {
-                       ++ma->is_ma;
-                       ma->did_print = 0;
-                       return;
-               }
+       struct ma_info *ma;
+       
+       ma = (struct ma_info *)cbuserdata;
+       lprintf(CTDL_DEBUG, "fixed_output_pre() type=<%s>\n", cbtype);  
+       if (!strcasecmp(cbtype, "multipart/alternative")) {
+               ++ma->is_ma;
+               ma->did_print = 0;
+               return;
+       }
 }
 
 /*
@@ -931,12 +930,15 @@ void fixed_output_post(char *name, char *filename, char *partnum, char *disp,
                void *content, char *cbtype, size_t length, char *encoding,
                void *cbuserdata)
 {
-               lprintf(CTDL_DEBUG, "fixed_output_post() type=<%s>\n", cbtype); 
-               if (!strcasecmp(cbtype, "multipart/alternative")) {
-                       --ma->is_ma;
-                       ma->did_print = 0;
-                       return;
-               }
+       struct ma_info *ma;
+       
+       ma = (struct ma_info *)cbuserdata;
+       lprintf(CTDL_DEBUG, "fixed_output_post() type=<%s>\n", cbtype); 
+       if (!strcasecmp(cbtype, "multipart/alternative")) {
+               --ma->is_ma;
+               ma->did_print = 0;
+       return;
+       }
 }
 
 /*
@@ -949,6 +951,9 @@ void fixed_output(char *name, char *filename, char *partnum, char *disp,
                char *ptr;
                char *wptr;
                size_t wlen;
+               struct ma_info *ma;
+       
+               ma = (struct ma_info *)cbuserdata;
 
                lprintf(CTDL_DEBUG, "fixed_output() type=<%s>\n", cbtype);      
 
@@ -998,6 +1003,9 @@ void choose_preferred(char *name, char *filename, char *partnum, char *disp,
 {
        char buf[SIZ];
        int i;
+       struct ma_info *ma;
+       
+       ma = (struct ma_info *)cbuserdata;
 
        if (ma->is_ma > 0) {
                for (i=0; i<num_tokens(CC->preferred_formats, '|'); ++i) {
@@ -1020,6 +1028,9 @@ void output_preferred(char *name, char *filename, char *partnum, char *disp,
        char buf[SIZ];
        int add_newline = 0;
        char *text_content;
+       struct ma_info *ma;
+       
+       ma = (struct ma_info *)cbuserdata;
 
        /* This is not the MIME part you're looking for... */
        if (strcasecmp(partnum, ma->chosen_part)) return;
@@ -1133,6 +1144,7 @@ int CtdlOutputPreLoadedMsg(
        char *nl;       /* newline string */
        int suppress_f = 0;
        int subject_found = 0;
+       struct ma_info *ma;
 
        /* buffers needed for RFC822 translation */
        char suser[SIZ];
@@ -1171,9 +1183,10 @@ int CtdlOutputPreLoadedMsg(
                } else {
                        /* Parse the message text component */
                        mptr = TheMessage->cm_fields['M'];
-                       mime_parser(mptr, NULL,
-                               *mime_download, NULL, NULL,
-                               NULL, 0);
+                       ma = malloc(sizeof(struct ma_info));
+                       memset(ma, 0, sizeof(struct ma_info));
+                       mime_parser(mptr, NULL, *mime_download, NULL, NULL, (void *)ma, 0);
+                       free(ma);
                        /* If there's no file open by this time, the requested
                         * section wasn't found, so print an error
                         */
@@ -1181,7 +1194,7 @@ int CtdlOutputPreLoadedMsg(
                                if (do_proto) cprintf(
                                        "%d Section %s not found.\n",
                                        ERROR + FILE_NOT_FOUND,
-                                       desired_section);
+                                       CC->download_desired_section);
                        }
                }
                return((CC->download_fp != NULL) ? om_ok : om_mime_error);
@@ -1466,16 +1479,17 @@ START_TEXT:
         * we use will display those parts as-is.
         */
        if (TheMessage->cm_format_type == FMT_RFC822) {
-               CtdlAllocUserData(SYM_MA_INFO, sizeof(struct ma_info));
-               memset(ma, 0, sizeof(struct ma_info));
 
                if (mode == MT_MIME) {
+                       ma = malloc(sizeof(struct ma_info));
+                       memset(ma, 0, sizeof(struct ma_info));
                        strcpy(ma->chosen_part, "1");
                        mime_parser(mptr, NULL,
                                *choose_preferred, *fixed_output_pre,
-                               *fixed_output_post, NULL, 0);
+                               *fixed_output_post, (void *)ma, 0);
                        mime_parser(mptr, NULL,
-                               *output_preferred, NULL, NULL, NULL, 0);
+                               *output_preferred, NULL, NULL, (void *)ma, 0);
+                       free(ma);
                }
                else {
                        mime_parser(mptr, NULL,
@@ -1592,11 +1606,11 @@ void cmd_msgp(char *cmdbuf)
 void cmd_opna(char *cmdbuf)
 {
        long msgid;
-
-       CtdlAllocUserData(SYM_DESIRED_SECTION, SIZ);
+       char desired_section[SIZ];
 
        msgid = extract_long(cmdbuf, 0);
        extract(desired_section, cmdbuf, 1);
+       safestrncpy(CC->download_desired_section, desired_section, sizeof CC->download_desired_section);
 
        CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1);
 }                      
@@ -1850,50 +1864,24 @@ void serialize_message(struct ser_ret *ret,             /* return values */
  * Back end for the ReplicationChecks() function
  */
 void check_repl(long msgnum, void *userdata) {
-       struct CtdlMessage *msg;
-       time_t timestamp = (-1L);
-
-       lprintf(CTDL_DEBUG, "check_repl() found message %ld\n", msgnum);
-       msg = CtdlFetchMessage(msgnum, 1);
-       if (msg == NULL) return;
-       if (msg->cm_fields['T'] != NULL) {
-               timestamp = atol(msg->cm_fields['T']);
-       }
-       CtdlFreeMessage(msg);
-
-       if (timestamp > msg_repl->highest) {
-               msg_repl->highest = timestamp;  /* newer! */
-               lprintf(CTDL_DEBUG, "newer!\n");
-               return;
-       }
-       lprintf(CTDL_DEBUG, "older!\n");
-
-       /* Existing isn't newer?  Then delete the old one(s). */
+       lprintf(CTDL_DEBUG, "check_repl() replacing message %ld\n", msgnum);
        CtdlDeleteMessages(CC->room.QRname, msgnum, "");
 }
 
 
 /*
- * Check to see if any messages already exist which carry the same Extended ID
- * as this one.  
+ * Check to see if any messages already exist which carry the same Exclusive ID
+ * as this one.  If any are found, delete them.
  *
- * 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;
 
-       lprintf(CTDL_DEBUG, "ReplicationChecks() started\n");
-       /* No extended id?  Don't do anything. */
+       /* No exclusive id?  Don't do anything. */
        if (msg->cm_fields['E'] == NULL) return 0;
        if (strlen(msg->cm_fields['E']) == 0) return 0;
-       lprintf(CTDL_DEBUG, "Extended ID: <%s>\n", msg->cm_fields['E']);
-
-       CtdlAllocUserData(SYM_REPL, sizeof(struct repl));
-       strcpy(msg_repl->extended_id, msg->cm_fields['E']);
-       msg_repl->highest = atol(msg->cm_fields['T']);
+       lprintf(CTDL_DEBUG, "Exclusive ID: <%s>\n", msg->cm_fields['E']);
 
        template = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
        memset(template, 0, sizeof(struct CtdlMessage));
@@ -1901,13 +1889,6 @@ int ReplicationChecks(struct CtdlMessage *msg) {
 
        CtdlForEachMessage(MSGS_ALL, 0L, NULL, template, check_repl, NULL);
 
-       /* 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);
        lprintf(CTDL_DEBUG, "ReplicationChecks() returning %d\n", abort_this);
        return(abort_this);
@@ -1981,7 +1962,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        lprintf(CTDL_DEBUG, "Learning what's inside\n");
        if (msg->cm_fields['M'] == NULL) {
                lprintf(CTDL_ERR, "ERROR: attempt to save message with NULL body\n");
-               return(-1);
+               return(-2);
        }
 
        switch (msg->cm_format_type) {
@@ -1993,28 +1974,25 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
                break;
        case 4:
                strcpy(content_type, "text/plain");
-               /* advance past header fields */
-               mptr = msg->cm_fields['M'];
-               a = strlen(mptr);
-               while ((--a) > 0) {
-                       if (!strncasecmp(mptr, "Content-type: ", 14)) {
-                               safestrncpy(content_type, mptr,
-                                           sizeof(content_type));
-                               strcpy(content_type, &content_type[14]);
-                               for (a = 0; a < strlen(content_type); ++a)
-                                       if ((content_type[a] == ';')
-                                           || (content_type[a] == ' ')
-                                           || (content_type[a] == 13)
-                                           || (content_type[a] == 10))
-                                               content_type[a] = 0;
-                               break;
+               mptr = bmstrstr(msg->cm_fields['M'],
+                               "Content-type: ", strncasecmp);
+               if (mptr != NULL) {
+                       safestrncpy(content_type, &mptr[14], 
+                                       sizeof content_type);
+                       for (a = 0; a < strlen(content_type); ++a) {
+                               if ((content_type[a] == ';')
+                                   || (content_type[a] == ' ')
+                                   || (content_type[a] == 13)
+                                   || (content_type[a] == 10)) {
+                                       content_type[a] = 0;
+                               }
                        }
-                       ++mptr;
                }
        }
 
        /* Goto the correct room */
-       lprintf(CTDL_DEBUG, "Selected room %s\n", (recps) ? CC->room.QRname : SENTITEMS);
+       lprintf(CTDL_DEBUG, "Selected room %s\n",
+               (recps) ? CC->room.QRname : SENTITEMS);
        strcpy(hold_rm, CC->room.QRname);
        strcpy(actual_rm, CC->room.QRname);
        if (recps != NULL) {
@@ -2050,16 +2028,16 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
 
        /* Perform "before save" hooks (aborting if any return nonzero) */
        lprintf(CTDL_DEBUG, "Performing before-save hooks\n");
-       if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return(-1);
+       if (PerformMessageHooks(msg, EVT_BEFORESAVE) > 0) return(-3);
 
-       /* If this message has an Extended ID, perform replication checks */
+       /* If this message has an Exclusive ID, perform replication checks */
        lprintf(CTDL_DEBUG, "Performing replication checks\n");
-       if (ReplicationChecks(msg) > 0) return(-1);
+       if (ReplicationChecks(msg) > 0) return(-4);
 
        /* Save it to disk */
        lprintf(CTDL_DEBUG, "Saving to disk\n");
        newmsgid = send_message(msg);
-       if (newmsgid <= 0L) return(-1);
+       if (newmsgid <= 0L) return(-5);
 
        /* Write a supplemental message info record.  This doesn't have to
         * be a critical section because nobody else knows about this message
@@ -2288,7 +2266,7 @@ char *CtdlReadMessageBody(char *terminator,       /* token signalling EOT */
 
        /* read in the lines of message text one by one */
        do {
-               if (client_gets(buf) < 1) finished = 1;
+               if (client_getln(buf, sizeof buf) < 1) finished = 1;
                if (!strcmp(buf, terminator)) finished = 1;
                if (crlf) {
                        strcat(buf, "\r\n");
@@ -2670,6 +2648,8 @@ void cmd_ent0(char *entargs)
        int err = 0;
        struct recptypes *valid = NULL;
        char subject[SIZ];
+       int do_confirm = 0;
+       long msgnum;
 
        unbuffer_output();
 
@@ -2678,6 +2658,7 @@ void cmd_ent0(char *entargs)
        anon_flag = extract_int(entargs, 2);
        format_type = extract_int(entargs, 3);
        extract(subject, entargs, 4);
+       do_confirm = extract_int(entargs, 6);
 
        /* first check to make sure the request is valid. */
 
@@ -2788,13 +2769,34 @@ void cmd_ent0(char *entargs)
        }
 
        /* Read in the message from the client. */
-       cprintf("%d send message\n", SEND_LISTING);
+       if (do_confirm) {
+               cprintf("%d send message\n", START_CHAT_MODE);
+       } else {
+               cprintf("%d send message\n", SEND_LISTING);
+       }
        msg = CtdlMakeMessage(&CC->user, recp,
                CC->room.QRname, anonymous, format_type,
                masquerade_as, subject, NULL);
 
        if (msg != NULL) {
-               CtdlSubmitMsg(msg, valid, "");
+               msgnum = CtdlSubmitMsg(msg, valid, "");
+
+               if (do_confirm) {
+                       cprintf("%ld\n", msgnum);
+                       if (msgnum >= 0L) {
+                               cprintf("Message accepted.\n");
+                       }
+                       else {
+                               cprintf("Internal error.\n");
+                       }
+                       if (msg->cm_fields['E'] != NULL) {
+                               cprintf("%s\n", msg->cm_fields['E']);
+                       } else {
+                               cprintf("\n");
+                       }
+                       cprintf("000\n");
+               }
+
                CtdlFreeMessage(msg);
        }
        CC->fake_postname[0] = '\0';
@@ -2981,7 +2983,7 @@ void cmd_move(char *args)
        }
 
        getuser(&CC->user, CC->curr_user);
-       ra = CtdlRoomAccess(&qtemp, &CC->user);
+       CtdlRoomAccess(&qtemp, &CC->user, &ra, NULL);
 
        /* Check for permission to perform this operation.
         * Remember: "CC->room" is source, "qtemp" is target.