]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Discovered that my system hasn't processed its refcount_adjustments queue in about...
[citadel.git] / citadel / msgbase.c
index 28601e5bebd4b122e4353fac637fd15b78012c26..87a01d63cf8e7a583483ad34e03c314c9d4f2cbf 100644 (file)
@@ -1451,6 +1451,7 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
        return(retcode);
 }
 
+
 char *qp_encode_email_addrs(char *source)
 {
        char user[256], node[256], name[256];
@@ -1469,9 +1470,8 @@ char *qp_encode_email_addrs(char *source)
        int InQuotes = 0;
        int i, n;
 
-       
-       if (source == NULL)
-               return source;
+       if (source == NULL) return source;
+       if (IsEmptyStr(source)) return source;
 
        AddrPtr = malloc (sizeof (long) * nAddrPtrMax);
        AddrUtf8 = malloc (sizeof (long) * nAddrPtrMax);
@@ -1479,14 +1479,17 @@ char *qp_encode_email_addrs(char *source)
        *AddrPtr = 0;
        i = 0;
        while (!IsEmptyStr (&source[i])) {
-               if (nColons > nAddrPtrMax){
+               if (nColons >= nAddrPtrMax){
                        long *ptr;
 
                        ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
                        memcpy (ptr, AddrPtr, sizeof (long) * nAddrPtrMax);
                        free (AddrPtr), AddrPtr = ptr;
+
                        ptr = (long *) malloc(sizeof (long) * nAddrPtrMax * 2);
-                       memset(ptr + sizeof (long) * nAddrPtrMax, 0, sizeof (long) * nAddrPtrMax - 1);
+                       memset(&ptr[nAddrPtrMax], 0, 
+                              sizeof (long) * nAddrPtrMax);
+
                        memcpy (ptr, AddrUtf8, sizeof (long) * nAddrPtrMax);
                        free (AddrUtf8), AddrUtf8 = ptr;
                        nAddrPtrMax *= 2;                               
@@ -1499,8 +1502,8 @@ char *qp_encode_email_addrs(char *source)
                if (source[i] == '"')
                        InQuotes = !InQuotes;
                if (!InQuotes && source[i] == ',') {
-                       nColons++;
                        AddrPtr[nColons] = i;
+                       nColons++;
                }
                i++;
        }
@@ -1514,12 +1517,12 @@ char *qp_encode_email_addrs(char *source)
        EncodedMaxLen = nColons * (sizeof(headerStr) + 3) + SourceLen * 3;
        Encoded = (char*) malloc (EncodedMaxLen);
 
-       for (i = 1; i <= nColons; i++)
+       for (i = 0; i < nColons; i++)
                source[AddrPtr[i]++] = '\0';
 
        nPtr = Encoded;
        *nPtr = '\0';
-       for (i = 0; i <= nColons && nPtr != NULL; i++) {
+       for (i = 0; i < nColons && nPtr != NULL; i++) {
                nmax = EncodedMaxLen - (nPtr - Encoded);
                if (AddrUtf8[i]) {
                        process_rfc822_addr(&source[AddrPtr[i]], 
@@ -1557,13 +1560,14 @@ char *qp_encode_email_addrs(char *source)
                        i--; /* do it once more with properly lengthened buffer */
                }
        }
-       for (i = 1; i <= nColons; i++)
+       for (i = 0; i < nColons; i++)
                source[--AddrPtr[i]] = ',';
        free(AddrUtf8);
        free(AddrPtr);
        return Encoded;
 }
 
+
 /*
  * Get a message off disk.  (returns om_* values found in msgbase.h)
  */
@@ -1577,7 +1581,7 @@ int CtdlOutputPreLoadedMsg(
 ) {
        int i, j, k;
        char buf[SIZ];
-       cit_uint8_t ch;
+       cit_uint8_t ch, prev_ch;
        char allkeys[30];
        char display_name[256];
        char *mptr, *mpptr;
@@ -1608,6 +1612,7 @@ int CtdlOutputPreLoadedMsg(
        if (!is_valid_message(TheMessage)) {
                CtdlLogPrintf(CTDL_ERR,
                        "ERROR: invalid preloaded message for output\n");
+               cit_backtrace ();
                return(om_no_such_msg);
        }
 
@@ -1764,15 +1769,18 @@ int CtdlOutputPreLoadedMsg(
                                        safestrncpy(suser, mptr, sizeof suser);
                                }
                                else if (i == 'Y') {
-                                       if (flags & QP_EADDR != 0) 
+                                       if ((flags & QP_EADDR) != 0) 
                                                mptr = qp_encode_email_addrs(mptr);
                                        cprintf("CC: %s%s", mptr, nl);
                                }
                                else if (i == 'P') {
                                        cprintf("Return-Path: %s%s", mptr, nl);
                                }
+                               else if (i == 'L') {
+                                       cprintf("List-ID: %s%s", mptr, nl);
+                               }
                                else if (i == 'V') {
-                                       if (flags & QP_EADDR != 0) 
+                                       if ((flags & QP_EADDR) != 0) 
                                                mptr = qp_encode_email_addrs(mptr);
                                        cprintf("Envelope-To: %s%s", mptr, nl);
                                }
@@ -1799,7 +1807,7 @@ int CtdlOutputPreLoadedMsg(
                                        }
                                        else
                                        {
-                                               if (flags & QP_EADDR != 0) 
+                                               if ((flags & QP_EADDR) != 0) 
                                                        mptr = qp_encode_email_addrs(mptr);
                                                cprintf("To: %s%s", mptr, nl);
                                        }
@@ -1897,6 +1905,7 @@ START_TEXT:
                        char outbuf[1024];
                        int outlen = 0;
                        int nllen = strlen(nl);
+                       prev_ch = 0;
                        while (ch=*mptr, ch!=0) {
                                if (ch==13) {
                                        /* do nothing */
@@ -1916,6 +1925,14 @@ START_TEXT:
                                                }
                                        }
                                }
+                               if (flags & ESC_DOT)
+                               {
+                                       if ((prev_ch == 10) && (ch == '.') && ((*(mptr+1) == 13) || (*(mptr+1) == 10)))
+                                       {
+                                               outbuf[outlen++] = '.';
+                                       }
+                               }
+                               prev_ch = ch;
                                ++mptr;
                                if (outlen > 1000) {
                                        client_write(outbuf, outlen);
@@ -2557,6 +2574,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        char *saved_rfc822_version = NULL;
        int qualified_for_journaling = 0;
        struct CitContext *CCC = CC;            /* CachedCitContext - performance boost */
+       char bounce_to[1024] = "";
 
        CtdlLogPrintf(CTDL_DEBUG, "CtdlSubmitMsg() called\n");
        if (is_valid_message(msg) == 0) return(-1);     /* self check */
@@ -2750,6 +2768,14 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,      /* message to save */
        CCC->user.posted = CCC->user.posted + 1;
        lputuser(&CCC->user);
 
+       /* Decide where bounces need to be delivered */
+       if (CCC->logged_in) {
+               snprintf(bounce_to, sizeof bounce_to, "%s@%s", CCC->user.fullname, config.c_nodename);
+       }
+       else {
+               snprintf(bounce_to, sizeof bounce_to, "%s@%s", msg->cm_fields['A'], msg->cm_fields['N']);
+       }
+
        /* If this is private, local mail, make a copy in the
         * recipient's mailbox and bump the reference count.
         */
@@ -2774,9 +2800,9 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                           instr = malloc(instr_alloc);
                           snprintf(instr, instr_alloc,
                        "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
-                       "bounceto|%s@%s\n",
+                       "bounceto|%s\n",
                        SPOOLMIME, newmsgid, (long)time(NULL),
-                       msg->cm_fields['A'], msg->cm_fields['N']
+                       bounce_to
                        );
 
                           imsg = malloc(sizeof(struct CtdlMessage));
@@ -2861,9 +2887,9 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                instr = malloc(instr_alloc);
                snprintf(instr, instr_alloc,
                        "Content-type: %s\n\nmsgid|%ld\nsubmitted|%ld\n"
-                       "bounceto|%s@%s\n",
+                       "bounceto|%s\n",
                        SPOOLMIME, newmsgid, (long)time(NULL),
-                       msg->cm_fields['A'], msg->cm_fields['N']
+                       bounce_to
                );
 
                for (i=0; i<num_tokens(recps->recp_internet, '|'); ++i) {
@@ -2896,14 +2922,14 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
        }
 
        if (collected_addresses != NULL) {
-               begin_critical_section(S_ATBF);
                aptr = (struct addresses_to_be_filed *)
                        malloc(sizeof(struct addresses_to_be_filed));
-               aptr->next = atbf;
                MailboxName(actual_rm, sizeof actual_rm,
                        &CCC->user, USERCONTACTSROOM);
                aptr->roomname = strdup(actual_rm);
                aptr->collected_addresses = collected_addresses;
+               begin_critical_section(S_ATBF);
+               aptr->next = atbf;
                atbf = aptr;
                end_critical_section(S_ATBF);
        }
@@ -4308,7 +4334,7 @@ int TDAP_ProcessAdjRefCountQueue(void)
        struct arcq arcq_rec;
        int num_records_processed = 0;
 
-       snprintf(file_arcq_temp, sizeof file_arcq_temp, "%s2", file_arcq);
+       snprintf(file_arcq_temp, sizeof file_arcq_temp, "%s.%04x", file_arcq, rand());
 
        begin_critical_section(S_SUPPMSGMAIN);
        if (arcfp != NULL) {
@@ -4371,7 +4397,7 @@ void TDAP_AdjRefCount(long msgnum, int incr)
        smi.meta_refcount += incr;
        PutMetaData(&smi);
        end_critical_section(S_SUPPMSGMAIN);
-       CtdlLogPrintf(CTDL_DEBUG, "msg %ld ref count delta %d, is now %d\n",
+       CtdlLogPrintf(CTDL_DEBUG, "msg %ld ref count delta %+d, is now %d\n",
                msgnum, incr, smi.meta_refcount);
 
        /* If the reference count is now zero, delete the message
@@ -4401,24 +4427,21 @@ void TDAP_AdjRefCount(long msgnum, int incr)
  * Note: this could be much more efficient.  Right now we use two temporary
  * files, and still pull the message into memory as with all others.
  */
-void CtdlWriteObject(char *req_room,           /* Room to stuff it in */
-                       char *content_type,     /* MIME type of this object */
-                       char *tempfilename,     /* Where to fetch it from */
+void CtdlWriteObject(char *req_room,                   /* Room to stuff it in */
+                       char *content_type,             /* MIME type of this object */
+                       char *raw_message,              /* Data to be written */
+                       off_t raw_length,               /* Size of raw_message */
                        struct ctdluser *is_mailbox,    /* Mailbox room? */
-                       int is_binary,          /* Is encoding necessary? */
-                       int is_unique,          /* Del others of this type? */
-                       unsigned int flags      /* Internal save flags */
+                       int is_binary,                  /* Is encoding necessary? */
+                       int is_unique,                  /* Del others of this type? */
+                       unsigned int flags              /* Internal save flags */
                        )
 {
 
-       FILE *fp;
        struct ctdlroom qrbuf;
        char roomname[ROOMNAMELEN];
        struct CtdlMessage *msg;
-
-       char *raw_message = NULL;
        char *encoded_message = NULL;
-       off_t raw_length = 0;
 
        if (is_mailbox != NULL) {
                MailboxName(roomname, sizeof roomname, is_mailbox, req_room);
@@ -4427,24 +4450,10 @@ void CtdlWriteObject(char *req_room,            /* Room to stuff it in */
                safestrncpy(roomname, req_room, sizeof(roomname));
        }
 
-       fp = fopen(tempfilename, "rb");
-       if (fp == NULL) {
-               CtdlLogPrintf(CTDL_CRIT, "Cannot open %s: %s\n",
-                       tempfilename, strerror(errno));
-               return;
-       }
-       fseek(fp, 0L, SEEK_END);
-       raw_length = ftell(fp);
-       rewind(fp);
        CtdlLogPrintf(CTDL_DEBUG, "Raw length is %ld\n", (long)raw_length);
 
-       raw_message = malloc((size_t)raw_length + 2);
-       fread(raw_message, (size_t)raw_length, 1, fp);
-       fclose(fp);
-
        if (is_binary) {
-               encoded_message = malloc((size_t)
-                       (((raw_length * 134) / 100) + 4096 ) );
+               encoded_message = malloc((size_t) (((raw_length * 134) / 100) + 4096 ) );
        }
        else {
                encoded_message = malloc((size_t)(raw_length + 4096));
@@ -4472,7 +4481,6 @@ void CtdlWriteObject(char *req_room,              /* Room to stuff it in */
                );
        }
        else {
-               raw_message[raw_length] = 0;
                memcpy(
                        &encoded_message[strlen(encoded_message)],
                        raw_message,
@@ -4480,8 +4488,6 @@ void CtdlWriteObject(char *req_room,              /* Room to stuff it in */
                );
        }
 
-       free(raw_message);
-
        CtdlLogPrintf(CTDL_DEBUG, "Allocating\n");
        msg = malloc(sizeof(struct CtdlMessage));
        memset(msg, 0, sizeof(struct CtdlMessage));
@@ -4571,20 +4577,9 @@ char *CtdlGetSysConfig(char *sysconfname) {
        return(conf);
 }
 
-void CtdlPutSysConfig(char *sysconfname, char *sysconfdata) {
-       char temp[PATH_MAX];
-       FILE *fp;
 
-       CtdlMakeTempFileName(temp, sizeof temp);
-
-       fp = fopen(temp, "w");
-       if (fp == NULL) return;
-       fprintf(fp, "%s", sysconfdata);
-       fclose(fp);
-
-       /* this handy API function does all the work for us */
-       CtdlWriteObject(SYSCONFIGROOM, sysconfname, temp, NULL, 0, 1, 0);
-       unlink(temp);
+void CtdlPutSysConfig(char *sysconfname, char *sysconfdata) {
+       CtdlWriteObject(SYSCONFIGROOM, sysconfname, sysconfdata, (strlen(sysconfdata)+1), NULL, 0, 1, 0);
 }