]> code.citadel.org Git - citadel.git/blobdiff - citadel/msgbase.c
* fix off by one while copying email headers
[citadel.git] / citadel / msgbase.c
index 9a6dc22b95cc90a6e8ed5e27190e120f2d4b4dbd..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);
@@ -2778,7 +2745,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        char content_type[SIZ];                 /* We have to learn this */
        char recipient[SIZ];
        long newmsgid;
-       char *mptr = NULL;
+       const char *mptr = NULL;
        struct ctdluser userbuf;
        int a, i;
        struct MetaData smi;
@@ -2875,7 +2842,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
 
        /* If the user is a twit, move to the twit room for posting */
        if (TWITDETECT) {
-               if (CCC->user.axlevel == 2) {
+               if (CCC->user.axlevel == AxProbU) {
                        strcpy(hold_rm, actual_rm);
                        strcpy(actual_rm, config.c_twitroom);
                        CtdlLogPrintf(CTDL_DEBUG, "Diverting to twit room\n");
@@ -3546,7 +3513,7 @@ int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf,
 
        }
 
-       if ((CC->user.axlevel < 2)
+       if ((CC->user.axlevel < AxProbU)
            && ((CC->room.QRflags & QR_MAILBOX) == 0)) {
                snprintf(errmsgbuf, n, "Need to be validated to enter "
                                "(except in %s> to sysop)", MAILROOM);
@@ -3571,7 +3538,7 @@ int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf,
 int CtdlCheckInternetMailPermission(struct ctdluser *who) {
 
        /* Do not allow twits to send Internet mail */
-       if (who->axlevel <= 2) return(0);
+       if (who->axlevel <= AxProbU) return(0);
 
        /* Globally enabled? */
        if (config.c_restrict == 0) return(1);
@@ -3580,7 +3547,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) {
        if (who->flags & US_INTERNET) return(2);
 
        /* Aide level access? */
-       if (who->axlevel >= 6) return(3);
+       if (who->axlevel >= AxAideU) return(3);
 
        /* No mail for you! */
        return(0);
@@ -3596,7 +3563,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) {
  *
  * Caller needs to free the result using free_recipients()
  */
-struct recptypes *validate_recipients(char *supplied_recipients, 
+struct recptypes *validate_recipients(const char *supplied_recipients, 
                                      const char *RemoteIdentifier, 
                                      int Flags) {
        struct recptypes *ret;
@@ -3932,7 +3899,7 @@ void cmd_ent0(char *entargs)
        if (IsEmptyStr(newusername)) {
                strcpy(newusername, CC->user.fullname);
        }
-       if (  (CC->user.axlevel < 6)
+       if (  (CC->user.axlevel < AxAideU)
           && (strcasecmp(newusername, CC->user.fullname))
           && (strcasecmp(newusername, CC->cs_inet_fn))
        ) {     
@@ -3982,7 +3949,7 @@ void cmd_ent0(char *entargs)
        if (  ( (CC->room.QRflags & QR_MAILBOX) && (!strcasecmp(&CC->room.QRname[11], MAILROOM)) )
           || ( (CC->room.QRflags & QR_MAILBOX) && (CC->curr_view == VIEW_MAILBOX) )
        ) {
-               if (CC->user.axlevel < 2) {
+               if (CC->user.axlevel < AxProbU) {
                        strcpy(recp, "sysop");
                        strcpy(cc, "");
                        strcpy(bcc, "");
@@ -4034,7 +4001,7 @@ void cmd_ent0(char *entargs)
                }
 
                if ( ( (valid_to->num_internet + valid_to->num_ignet + valid_cc->num_internet + valid_cc->num_ignet + valid_bcc->num_internet + valid_bcc->num_ignet) > 0)
-                  && (CC->user.axlevel < 4) ) {
+                  && (CC->user.axlevel < AxNetU) ) {
                        cprintf("%d Higher access required for network mail.\n",
                                ERROR + HIGHER_ACCESS_REQUIRED);
                        free_recipients(valid_to);
@@ -4393,7 +4360,7 @@ void cmd_move(char *args)
        permit = 0;
 
        /* Aides can move/copy */
-       if (CC->user.axlevel >= 6) permit = 1;
+       if (CC->user.axlevel >= AxAideU) permit = 1;
 
        /* Room aides can move/copy */
        if (CC->user.usernum == CC->room.QRroomaide) permit = 1;