]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Disable the XMPP-mortuary code. It's not ready for production yet.
[citadel.git] / citadel / msgbase.c
index 40635193ad286fe861b63eda2441e1489848901c..9d6c6acf057e3f1ed47b6cdae87ab0f4c7ff3f2b 100644 (file)
@@ -2,22 +2,22 @@
  * $Id$
  *
  * Implements the message store.
- * 
+ *
  * Copyright (c) 1987-2010 by the citadel.org team
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
@@ -971,6 +971,12 @@ void memfmout(
                        }
                }
        }
+       if (len) {
+               client_write(outbuf, len);
+               len = 0;
+               client_write(nl, nllen);
+               column = 0;
+       }
 }
 
 
@@ -1164,7 +1170,8 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body)
        if ( (ret->cm_fields['M'] == NULL) && (with_body) ) {
                dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long));
                if (dmsgtext != NULL) {
-                       ret->cm_fields['M'] = strdup(dmsgtext->ptr);
+                       ret->cm_fields['M'] = dmsgtext->ptr;
+                       dmsgtext->ptr = NULL;
                        cdb_free(dmsgtext);
                }
        }
@@ -1566,7 +1573,7 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
 
 char *qp_encode_email_addrs(char *source)
 {
-       char user[256], node[256], name[256];
+       char *user, *node, *name;
        const char headerStr[] = "=?UTF-8?Q?";
        char *Encoded;
        char *EncodedName;
@@ -1584,6 +1591,8 @@ char *qp_encode_email_addrs(char *source)
 
        if (source == NULL) return source;
        if (IsEmptyStr(source)) return source;
+       cit_backtrace();
+       CtdlLogPrintf(CTDL_DEBUG, "qp_encode_email_addrs: [%s]\n", source);
 
        AddrPtr = malloc (sizeof (long) * nAddrPtrMax);
        AddrUtf8 = malloc (sizeof (long) * nAddrPtrMax);
@@ -1631,6 +1640,10 @@ char *qp_encode_email_addrs(char *source)
 
        for (i = 0; i < nColons; i++)
                source[AddrPtr[i]++] = '\0';
+       /* TODO: if libidn, this might get larger*/
+       user = malloc(SourceLen + 1);
+       node = malloc(SourceLen + 1);
+       name = malloc(SourceLen + 1);
 
        nPtr = Encoded;
        *nPtr = '\0';
@@ -1674,6 +1687,10 @@ char *qp_encode_email_addrs(char *source)
        }
        for (i = 0; i < nColons; i++)
                source[--AddrPtr[i]] = ',';
+
+       free(user);
+       free(node);
+       free(name);
        free(AddrUtf8);
        free(AddrPtr);
        return Encoded;
@@ -1716,7 +1733,7 @@ int CtdlOutputPreLoadedMsg(
                int crlf,               /* Use CRLF newlines instead of LF? */
                int flags               /* should the bessage be exported clean? */
 ) {
-       int i, j, k;
+       int i, j, k, n;
        char buf[SIZ];
        cit_uint8_t ch, prev_ch;
        char allkeys[30];
@@ -1868,8 +1885,8 @@ int CtdlOutputPreLoadedMsg(
                }
 
                /* Now spew the header fields in the order we like them. */
-               safestrncpy(allkeys, FORDER, sizeof allkeys);
-               for (i=0; i<strlen(allkeys); ++i) {
+               n = safestrncpy(allkeys, FORDER, sizeof allkeys);
+               for (i=0; i<n; ++i) {
                        k = (int) allkeys[i];
                        if (k != 'M') {
                                if ( (TheMessage->cm_fields[k] != NULL)
@@ -2042,45 +2059,56 @@ START_TEXT:
                                (void *)&ma, 0);
                }
                else if (mode == MT_RFC822) {   /* unparsed RFC822 dump */
-                       char *start_of_text = NULL;
-                       start_of_text = strstr(mptr, "\n\r\n");
-                       if (start_of_text == NULL) start_of_text = strstr(mptr, "\n\n");
-                       if (start_of_text == NULL) start_of_text = mptr;
-                       ++start_of_text;
-                       start_of_text = strstr(start_of_text, "\n");
-                       ++start_of_text;
+                       int eoh = 0;
+                       const char *StartOfText = StrBufNOTNULL;
 
                        char outbuf[1024];
                        int outlen = 0;
                        int nllen = strlen(nl);
-                       prev_ch = 0;
-                       while (ch=*mptr, ch!=0) {
-                               if (ch==13) {
+                       prev_ch = '\0';
+                       while (*mptr != '\0') {
+                               if (*mptr == '\r') {
                                        /* do nothing */
                                }
                                else {
-                                       if (
-                                               ((headers_only == HEADERS_NONE) && (mptr >= start_of_text))
-                                          ||   ((headers_only == HEADERS_ONLY) && (mptr < start_of_text))
-                                          ||   ((headers_only != HEADERS_NONE) && (headers_only != HEADERS_ONLY))
+                                       if ((!eoh) &&
+                                           (*mptr == '\n'))
+                                       {
+                                               eoh = (*(mptr+1) == '\r') && (*(mptr+2) == '\n');
+                                               if (!eoh)
+                                                       eoh = *(mptr+1) == '\n';
+                                               if (eoh)
+                                               {
+                                                       StartOfText = mptr;
+                                                       StartOfText = strchr(StartOfText, '\n');
+                                                       StartOfText = strchr(StartOfText, '\n');
+                                               }
+                                       }
+                                       if (((headers_only == HEADERS_NONE) && (mptr >= StartOfText)) ||
+                                           ((headers_only == HEADERS_ONLY) && (mptr < StartOfText)) ||
+                                           ((headers_only != HEADERS_NONE) && 
+                                            (headers_only != HEADERS_ONLY))
                                        ) {
-                                               if (ch == 10) {
-                                                       sprintf(&outbuf[outlen], "%s", nl);
+                                               if (*mptr == '\n') {
+                                                       memcpy(&outbuf[outlen], nl, nllen);
                                                        outlen += nllen;
+                                                       outbuf[outlen] = '\0';
                                                }
                                                else {
-                                                       outbuf[outlen++] = ch;
+                                                       outbuf[outlen++] = *mptr;
                                                }
                                        }
                                }
                                if (flags & ESC_DOT)
                                {
-                                       if ((prev_ch == 10) && (ch == '.') && ((*(mptr+1) == 13) || (*(mptr+1) == 10)))
+                                       if ((prev_ch == '\n') && 
+                                           (*mptr == '.') && 
+                                           ((*(mptr+1) == '\r') || (*(mptr+1) == '\n')))
                                        {
                                                outbuf[outlen++] = '.';
                                        }
+                                       prev_ch = *mptr;
                                }
-                               prev_ch = ch;
                                ++mptr;
                                if (outlen > 1000) {
                                        client_write(outbuf, outlen);
@@ -2211,7 +2239,6 @@ DONE:     /* now we're done */
 }
 
 
-
 /*
  * display a message (mode 0 - Citadel proprietary)
  */
@@ -2358,8 +2385,8 @@ void cmd_dlat(char *cmdbuf)
  * this mode of operation only works if we're saving a single message.)
  */
 int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs,
-                               int do_repl_check, struct CtdlMessage *supplied_msg)
-{
+                       int do_repl_check, struct CtdlMessage *supplied_msg, int suppress_refcount_adj
+{
        int i, j, unique;
        char hold_rm[ROOMNAMELEN];
        struct cdbdata *cdbfr;
@@ -2374,8 +2401,9 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
        int num_msgs_to_be_merged = 0;
 
        CtdlLogPrintf(CTDL_DEBUG,
-               "CtdlSaveMsgPointersInRoom(room=%s, num_msgs=%d, repl=%d)\n",
-               roomname, num_newmsgs, do_repl_check);
+               "CtdlSaveMsgPointersInRoom(room=%s, num_msgs=%d, repl=%d, suppress_rca=%d)\n",
+               roomname, num_newmsgs, do_repl_check, suppress_refcount_adj
+       );
 
        strcpy(hold_rm, CC->room.QRname);
 
@@ -2496,8 +2524,10 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
        CtdlGetRoom(&CC->room, hold_rm);
 
        /* Bump the reference count for all messages which were merged */
-       for (i=0; i<num_msgs_to_be_merged; ++i) {
-               AdjRefCount(msgs_to_be_merged[i], +1);
+       if (!suppress_refcount_adj) {
+               for (i=0; i<num_msgs_to_be_merged; ++i) {
+                       AdjRefCount(msgs_to_be_merged[i], +1);
+               }
        }
 
        /* Free up memory... */
@@ -2517,7 +2547,7 @@ int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newms
 int CtdlSaveMsgPointerInRoom(char *roomname, long msgid,
                        int do_repl_check, struct CtdlMessage *supplied_msg)
 {
-       return CtdlSaveMsgPointersInRoom(roomname, &msgid, 1, do_repl_check, supplied_msg);
+       return CtdlSaveMsgPointersInRoom(roomname, &msgid, 1, do_repl_check, supplied_msg, 0);
 }
 
 
@@ -2749,7 +2779,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        char *hold_R, *hold_D;
        char *collected_addresses = NULL;
        struct addresses_to_be_filed *aptr = NULL;
-       char *saved_rfc822_version = NULL;
+       StrBuf *saved_rfc822_version = NULL;
        int qualified_for_journaling = 0;
        CitContext *CCC = CC;           /* CachedCitContext - performance boost */
        char bounce_to[1024] = "";
@@ -2900,15 +2930,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,     /* message to save */
                CtdlLogPrintf(CTDL_ALERT, "CCC->redirect_buffer is not NULL during message submission!\n");
                abort();
        }
-       CCC->redirect_buffer = malloc(SIZ);
-       CCC->redirect_len = 0;
-       CCC->redirect_alloc = SIZ;
+       CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
        CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR);
-       smi.meta_rfc822_length = CCC->redirect_len;
+       smi.meta_rfc822_length = StrLength(CCC->redirect_buffer);
        saved_rfc822_version = CCC->redirect_buffer;
        CCC->redirect_buffer = NULL;
-       CCC->redirect_len = 0;
-       CCC->redirect_alloc = 0;
 
        PutMetaData(&smi);
 
@@ -3145,7 +3171,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                        JournalBackgroundSubmit(msg, saved_rfc822_version, recps);
                }
                else {
-                       free(saved_rfc822_version);
+                       FreeStrBuf(&saved_rfc822_version);
                }
        }
 
@@ -4393,7 +4419,7 @@ void cmd_move(char *args)
        /*
         * Do the copy
         */
-       err = CtdlSaveMsgPointersInRoom(targ, msgs, num_msgs, 1, NULL);
+       err = CtdlSaveMsgPointersInRoom(targ, msgs, num_msgs, 1, NULL, 0);
        if (err != 0) {
                cprintf("%d Cannot store message(s) in %s: error %d\n",
                        err, targ, err);
@@ -4467,6 +4493,10 @@ void AdjRefCount(long msgnum, int incr)
        struct arcq new_arcq;
        int rv = 0;
 
+       CtdlLogPrintf(CTDL_DEBUG, "AdjRefCount() msg %ld ref count delta %+d\n",
+               msgnum, incr
+       );
+
        begin_critical_section(S_SUPPMSGMAIN);
        if (arcfp == NULL) {
                arcfp = fopen(file_arcq, "ab+");
@@ -4580,8 +4610,9 @@ 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",
-               msgnum, incr, smi.meta_refcount);
+       CtdlLogPrintf(CTDL_DEBUG, "TDAP_AdjRefCount() 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
         * (and its supplementary record as well).