]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* fix off by one while copying email headers
[citadel.git] / citadel / msgbase.c
index df4d224d03b209908ee244c2ecef04f4f75b3f5a..429f17a8b4e6b56baef7f91a26f6f20fb17c8d94 100644 (file)
@@ -927,92 +927,56 @@ void do_help_subst(char *buffer)
  */
 void memfmout(
        char *mptr,             /* where are we going to get our text from? */
-       const char *nl)         /* string to terminate lines with */
-{
-       StrBuf *OutBuf;
-       char *LineStart;
-       char *LastBlank;
-       size_t len;
-       size_t NLLen;
-       char *eptr;
-       int NLFound, NLFoundLastTime;
-       int Found;
-
-       len = strlen (mptr);
-       NLLen = strlen (nl);
-       eptr = mptr + len;
-
-       OutBuf = NewStrBufPlain(NULL, 200);
-       
-       NLFound = NLFoundLastTime = 0;
-       do {
-               size_t i;
-
-               LineStart = LastBlank = mptr;
-               Found = 'x';
-               i = 0;
-               while (Found == 'x')
-               {
-                       if (LineStart[i] == '\n')
-                               Found = '\n';
-                       else if (LineStart[i] == '\r')
-                               Found = '\r';
-                       else if (LineStart[i] == ' ') 
-                       {
-                               LastBlank = &LineStart[i];
-                               i++;
+       const char *nl          /* string to terminate lines with */
+) {
+       int column = 0;
+       char ch = 0;
+       char outbuf[1024];
+       int len = 0;
+       int nllen = 0;
+
+       if (!mptr) return;
+       nllen = strlen(nl);
+       while (ch=*(mptr++), ch > 0) {
+
+               if (ch == '\n') {
+                       client_write(outbuf, len);
+                       len = 0;
+                       client_write(nl, nllen);
+                       column = 0;
+               }
+               else if (ch == '\r') {
+                       /* Ignore carriage returns.  Newlines are always LF or CRLF but never CR. */
+               }
+               else if (isspace(ch)) {
+                       if (column > 72) {              /* Beyond 72 columns, break on the next space */
+                               client_write(outbuf, len);
+                               len = 0;
+                               client_write(nl, nllen);
+                               column = 0;
+                       }
+                       else {
+                               outbuf[len++] = ch;
+                               ++column;
                        }
-                       else if ((i > 80) && (LineStart != LastBlank))
-                               Found = ' ';
-                       else if (LineStart[i] == '\0')
-                               Found = '\0';
-                       else i++;
                }
-               switch (Found)
-               {
-               case '\n':
-                       if (LineStart[i + 1] == '\r')
-                               mptr = &LineStart[i + 2];
-                       else 
-                               mptr = &LineStart[i + 1];
-                       i--;
-                       NLFound = 1;
-                       break;
-               case '\r':
-                       if (LineStart[i + 1] == '\n')
-                               mptr = &LineStart[i + 2];
-                       else 
-                               mptr = &LineStart[i + 1];
-                       i--;
-                       NLFound = 1;
-                       break;
-               case '\0':
-                       mptr = &LineStart[i + 1];
-                       i--;
-                       NLFound = 0;
-                       break;
-               case ' ':
-                       mptr = LastBlank + 1;
-                       i = LastBlank - LineStart;
-                       NLFound = 0;
-                       break;
-               case 'x':
-                       /* WHUT? */
-                       while (*mptr != '\0') mptr++;
-                       break;
+               else {
+                       outbuf[len++] = ch;
+                       ++column;
+                       if (column > 1000) {            /* Beyond 1000 columns, break anywhere */
+                               client_write(outbuf, len);
+                               len = 0;
+                               client_write(nl, nllen);
+                               column = 0;
+                       }
                }
-               if (NLFoundLastTime)
-                       StrBufPlain(OutBuf, HKEY(" "));
-               else
-                       FlushStrBuf(OutBuf);
-               StrBufAppendBufPlain(OutBuf, LineStart, i, 0);
-               StrBufAppendBufPlain(OutBuf, nl, NLLen, 0);
-
-               cputbuf(OutBuf);
-               NLFoundLastTime = NLFound;
-       } while (*mptr != '\0');
-
-       FreeStrBuf(&OutBuf);
+       }
+       if (len) {
+               client_write(outbuf, len);
+               len = 0;
+               client_write(nl, nllen);
+               column = 0;
+       }
 }
 
 
@@ -2084,45 +2048,48 @@ 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;
 
                        char outbuf[1024];
                        int outlen = 0;
                        int nllen = strlen(nl);
                        prev_ch = 0;
-                       while (ch=*mptr, ch!=0) {
-                               if (ch==13) {
+                       while (*mptr != '\0') {
+                               if (*mptr == '\r') {
                                        /* do nothing */
                                }
                                else {
+                                       if ((!eoh) &&
+                                           (*mptr == '\n'))
+                                       {
+                                               eoh = (*(mptr+1) == '\r') && (*(mptr+2) == '\n');
+                                               if (!eoh)
+                                                       eoh = *(mptr+1) == '\n';
+                                       }
+
                                        if (
-                                               ((headers_only == HEADERS_NONE) && (mptr >= start_of_text))
-                                          ||   ((headers_only == HEADERS_ONLY) && (mptr < start_of_text))
+                                               ((headers_only == HEADERS_NONE) && (eoh))
+                                          ||   ((headers_only == HEADERS_ONLY) && (!eoh))
                                           ||   ((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 = ch;
+                               prev_ch = *mptr;
                                ++mptr;
                                if (outlen > 1000) {
                                        client_write(outbuf, outlen);