]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* Blank out the Envelope-to: header when reading messages via POP or IMAP. Resolves...
[citadel.git] / citadel / msgbase.c
index 8e94f87b834963a79fc6943320db15e7b97afefe..d5be1bb33ff99ed7d997f2380a0316cff8df026b 100644 (file)
@@ -353,7 +353,6 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
        StrBuf *histr;
        const char *pvset;
        char *is_set;   /* actually an array of booleans */
-       int w = 0;
 
        /* Don't bother doing *anything* if we were passed a list of zero messages */
        if (num_target_msgnums < 1) {
@@ -424,7 +423,8 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
        lostr = NewStrBuf();
        histr = NewStrBuf();
        pvset = NULL;
-       while (StrBufExtract_NextToken(setstr, vset, &pvset, ',')) {
+       while (StrBufExtract_NextToken(setstr, vset, &pvset, ',') >= 0) {
+
                StrBufExtract_token(lostr, setstr, 0, ':');
                if (StrBufNum_tokens(setstr, ':') >= 2) {
                        StrBufExtract_token(histr, setstr, 1, ':');
@@ -468,14 +468,11 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
                        }
                }
 
-               w = 0;  /* set to 1 if we write something to the string */
-
                if ((was_seen == 0) && (is_seen == 1)) {
                        lo = msglist[i];
                }
                else if ((was_seen == 1) && (is_seen == 0)) {
                        hi = msglist[i-1];
-                       w = 1;
 
                        if (StrLength(vset) > 0) {
                                StrBufAppendBufPlain(vset, HKEY(","), 0);
@@ -487,8 +484,8 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
                                StrBufAppendPrintf(vset, "%ld:%ld", lo, hi);
                        }
                }
-               else if ((is_seen) && (i == num_msgs - 1)) {
-                       w = 1;
+
+               if ((is_seen) && (i == num_msgs - 1)) {
                        if (StrLength(vset) > 0) {
                                StrBufAppendBufPlain(vset, HKEY(","), 0);
                        }
@@ -500,27 +497,48 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
                        }
                }
 
-               /* If the string is getting too long, truncate it at the beginning; repeat up to 9 times * /
-               if (w) for (j=0; j<9; ++j) {
-                       if ((StrLength(vset) + 20) > sizeof vset) {
-                               remove_token(vset, 0, ',');
-                               if (which_set == ctdlsetseen_seen) {
-                                       char temp[SIZ];
-                                       sprintf(temp, "1:%ld,", atol(vset)-1L);
-                                       strcat(temp, vset);
-                                       strcpy(vset, temp);
-                               }
-                       }
-               }
-               we don't get to long anymore.
-               */
-
                was_seen = is_seen;
        }
 
-       while (StrLength(vset) > SIZ)
+       /*
+        * We will have to stuff this string back into a 4096 byte buffer, so if it's
+        * larger than that now, truncate it by removing tokens from the beginning.
+        * The limit of 100 iterations is there to prevent an infinite loop in case
+        * something unexpected happens.
+        */
+       int number_of_truncations = 0;
+       while ( (StrLength(vset) > SIZ) && (number_of_truncations < 100) ) {
+               StrBufRemove_token(vset, 0, ',');
+               ++number_of_truncations;
+       }
+
+       /*
+        * If we're truncating the sequence set of messages marked with the 'seen' flag,
+        * we want the earliest messages (the truncated ones) to be marked, not unmarked.
+        * Otherwise messages at the beginning will suddenly appear to be 'unseen'.
+        */
+       if ( (which_set == ctdlsetseen_seen) && (number_of_truncations > 0) ) {
+               StrBuf *first_tok;
+               first_tok = NewStrBuf();
+               StrBufExtract_token(first_tok, vset, 0, ',');
                StrBufRemove_token(vset, 0, ',');
 
+               if (StrBufNum_tokens(first_tok, ':') > 1) {
+                       StrBufRemove_token(first_tok, 0, ':');
+               }
+               
+               StrBuf *new_set;
+               new_set = NewStrBuf();
+               StrBufAppendBufPlain(new_set, HKEY("1:"), 0);
+               StrBufAppendBuf(new_set, first_tok, 0);
+               StrBufAppendBufPlain(new_set, HKEY(":"), 0);
+               StrBufAppendBuf(new_set, vset, 0);
+
+               FreeStrBuf(&vset);
+               FreeStrBuf(&first_tok);
+               vset = new_set;
+       }
+
        CtdlLogPrintf(CTDL_DEBUG, " after update: %s\n", ChrPtr(vset));
 
        /* Decide which message set we're manipulating */
@@ -999,6 +1017,7 @@ void mime_download(char *name, char *filename, char *partnum, char *disp,
                   void *content, char *cbtype, char *cbcharset, size_t length,
                   char *encoding, char *cbid, void *cbuserdata)
 {
+       int rv = 0;
 
        /* Silently go away if there's already a download open. */
        if (CC->download_fp != NULL)
@@ -1012,7 +1031,7 @@ void mime_download(char *name, char *filename, char *partnum, char *disp,
                if (CC->download_fp == NULL)
                        return;
        
-               fwrite(content, length, 1, CC->download_fp);
+               rv = fwrite(content, length, 1, CC->download_fp);
                fflush(CC->download_fp);
                rewind(CC->download_fp);
        
@@ -1422,7 +1441,7 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
                  int do_proto,         /* do Citadel protocol responses? */
                  int crlf,             /* Use CRLF newlines instead of LF? */
                  char *section,        /* NULL or a message/rfc822 section */
-                 int flags             /* should the bessage be exported clean? */
+                 int flags             /* various flags; see msgbase.h */
 ) {
        struct CtdlMessage *TheMessage = NULL;
        int retcode = om_no_such_msg;
@@ -1688,6 +1707,13 @@ int CtdlOutputPreLoadedMsg(
                return(om_no_such_msg);
        }
 
+       /* Suppress envelope recipients if required to avoid disclosing BCC addresses.
+        * Pad it with spaces in order to avoid changing the RFC822 length of the message.
+        */
+       if ( (flags & SUPPRESS_ENV_TO) && (TheMessage->cm_fields['V'] != NULL) ) {
+               memset(TheMessage->cm_fields['V'], ' ', strlen(TheMessage->cm_fields['V']));
+       }
+               
        /* Are we downloading a MIME component? */
        if (mode == MT_DOWNLOAD) {
                if (TheMessage->cm_format_type != FMT_RFC822) {
@@ -1795,7 +1821,7 @@ int CtdlOutputPreLoadedMsg(
                      if (haschar(TheMessage->cm_fields['N'], '.') == 0) {
                        suppress_f = 1;
                }
-               
+
                /* Now spew the header fields in the order we like them. */
                safestrncpy(allkeys, FORDER, sizeof allkeys);
                for (i=0; i<strlen(allkeys); ++i) {
@@ -2653,6 +2679,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        struct CitContext *CCC = CC;            /* CachedCitContext - performance boost */
        char bounce_to[1024] = "";
        size_t tmp = 0;
+       int rv = 0;
 
        CtdlLogPrintf(CTDL_DEBUG, "CtdlSubmitMsg() called\n");
        if (is_valid_message(msg) == 0) return(-1);     /* self check */
@@ -2935,7 +2962,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
                                         (long) getpid(), CCC->cs_pid, ++seqnum);
                        network_fp = fopen(submit_filename, "wb+");
                        if (network_fp != NULL) {
-                               fwrite(smr.ser, smr.len, 1, network_fp);
+                               rv = fwrite(smr.ser, smr.len, 1, network_fp);
                                fclose(network_fp);
                        }
                        free(smr.ser);
@@ -4359,6 +4386,7 @@ void PutMetaData(struct MetaData *smibuf)
 void AdjRefCount(long msgnum, int incr)
 {
        struct arcq new_arcq;
+       int rv = 0;
 
        begin_critical_section(S_SUPPMSGMAIN);
        if (arcfp == NULL) {
@@ -4388,7 +4416,7 @@ void AdjRefCount(long msgnum, int incr)
 
        new_arcq.arcq_msgnum = msgnum;
        new_arcq.arcq_delta = incr;
-       fwrite(&new_arcq, sizeof(struct arcq), 1, arcfp);
+       rv = fwrite(&new_arcq, sizeof(struct arcq), 1, arcfp);
        fflush(arcfp);
 
        return;