OSSP CVS Repository

ossp - Difference in ossp-pkg/lmtp2nntp/msg.c versions 1.9 and 1.10
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/lmtp2nntp/msg.c 1.9 -> 1.10

--- msg.c        2001/08/23 09:12:30     1.9
+++ msg.c        2001/08/27 13:45:53     1.10
@@ -39,7 +39,7 @@
 {
     if (msg == NULL)
         return;
-                                             /*FIXME what about non-graceful aborts? */
+
     if (msg->azEnvgroups != NULL)
         free(msg->azEnvgroups);
     if (msg->cpMsg != NULL)
@@ -99,7 +99,7 @@
 
     /* split message into header and body */
     if (str_parse(msg->cpMsg, "m/((?:.*?)\\n)\\n(.*)$/s", &cpHeaders, &msg->cpBody) <= 0)
-        return MSG_ERR_SPLITSPLITBODY;
+        return MSG_ERR_SPLITHEADBODY;
 
     /* replace envelope From w/o colon by X-F: pseudotag. This eliminates the
      * special case of having one header, which is really an embedded
@@ -110,19 +110,14 @@
         memcpy(cpHeaders, "X-F:", 4);
 
     /* unwrap header lines */
-    /*FIXME poor man's s///g simulator as current str library doesn't support //global substitution */
+    /* poor man's s///g simulator as current str library doesn't support global substitution */
     while (str_parse(cpHeaders, "s/(.*?)\\n[ \\t]+(.*)/$1 $2/s", &cpRem) > 0) {
         free(cpHeaders);
         cpHeaders = cpRem;
     }
 
     /* split header lines into names and values */
-    /*FIXME str enhancement requests and bugs to be fixed */
-    /*FIXME - fix bug "not" [^...] working */
-    /*FIXME - improve str_parse(foo, "...", &foo) should free foo() on it's own */
-    /*FIXME - add "global" in s/search/replace/g (see above "unwrap hader lines") */
-    while (str_parse(cpHeaders, "m/^([\\w-]+?:)[ \\t]*(.*?)[ \\t]*\\n(.*)/s",
-                     &cpName, &cpValue, &cpRem) > 0) {
+    while (str_parse(cpHeaders, "m/^([\\w-]+?:)[ \\t]*([^\\n]*?)[ \\t]*\\n(.*)/s", &cpName, &cpValue, &cpRem) > 0) {
         free(cpHeaders);
         cpHeaders = cpRem;
         argz_add(&msg->azHeaders, &msg->asHeaders, cpName);
@@ -194,7 +189,7 @@
             return MSG_ERR_MEM;
     }
     argz_add(&msg->azHeaders, &msg->asHeaders, "Path:");
-    argz_add(&msg->azHeaders, &msg->asHeaders, "not-for-mail"); /*FIXME */
+    argz_add(&msg->azHeaders, &msg->asHeaders, "not-for-mail");
 
     return MSG_OK;
 }
@@ -205,6 +200,7 @@
     char        *cpRem;
     char       **aHeaders;
     int          i;
+    int          o;
     char        *cpCut;
     char        *cpWrap;
     char         c;
@@ -248,36 +244,47 @@
     }
     free(aHeaders);
 
-    /* fold headers */
+    /* fold headers
+     *
+     * A logical line is split into one or more physical '\n'-terminated
+     * lines. The physical line is never longer than WRAPAT characters. This
+     * includes the folded data and the header name + colon + space for the
+     * first line and WRAPUSING string prefix for all other lines. Leading and
+     * trailing blanks of folded lines are removed while blanks inside the
+     * line are preserved.  The header is never left alone in a physical line.
+     * Fragments exceeding WRAPAT characters without having a blank as a
+     * splitting point are forcibly cut at a non-blank character.
+     */
     cp = NULL;
     while ((cp = argz_next(msg->azHeaders, msg->asHeaders, cp)) != NULL) {
-        if (strlen(cp) >= WRAPAT) {
+        if (strlen(cp) > WRAPAT) {
             cpRem = cp;
             cpWrap = NULL;
-            while (strlen(cpRem) >= WRAPAT) {
-                for (i = WRAPAT; i >= 1 && (cpRem[i] != ' ') && (cpRem[i] != '\t'); i--);
-                if (i == 0)
-                    i = WRAPAT; /* sorry, hard cut at non-whitespace */
-                if (i < WRAPAT)
-                    i++; /* we don't care about the whitespace itself */
-                cpCut = str_dup(cpRem, i);
-                /*FIXME 1.) continue searching downwards skipping all whitespaces and 2.) as we know the length replace str_dup/ strcat/ free with strncat only */
-                if (cpWrap == NULL) {
-                    if ((cpWrap = (char *)malloc(strlen(cpCut)+strlen(WRAPUSING)+1)) == NULL)
-                        return MSG_ERR_MEM;
-                    *cpWrap = '\0';
-                }
-                else {
-                    if ((cpWrap = (char *)realloc(cpWrap, strlen(cpWrap)+strlen(cpCut)+strlen(WRAPUSING)+1)) == NULL)
-                        return MSG_ERR_MEM;
-                    strcat(cpWrap, WRAPUSING);
-                }
-                strcat(cpWrap, cpCut);
-                free(cpCut);
+            for (o = 0; (cpRem[o] != ':') && (cpRem[o] != '\0'); o++); /* offset name so at least one char of value remains in first line */
+            o += 2; /* skip ": " */
+            while ((strlen(cpRem) + (cpWrap == NULL ? 0 : strlen(WRAPUSING))) > WRAPAT) {
+                for (i = WRAPAT - 1 - (cpWrap == NULL ? 0 : strlen(WRAPUSING)); (i >= o) && !isblank(cpRem[i]); i--);
+                if (i < o)
+                    i = WRAPAT - 1 - (cpWrap == NULL ? 0 : strlen(WRAPUSING) - 1); /* sorry, forced cut at non-blank */
+                cpCut = cpRem;
                 cpRem += i;
+                for (; (isblank(*cpRem) && (*cpRem != '\0')); cpRem++); /* skip next lines leading blanks */
+                for (; (i >= o) && isblank(cpCut[i-1]); i--); /* chop off this lines trailing blanks */
+                if (i >= o) { /* only keep line fragment if some non-blanks inside */
+                    if (cpWrap == NULL) {
+                        if ((cpWrap = (char *)malloc(i+strlen(WRAPUSING)+1)) == NULL)
+                            return MSG_ERR_MEM;
+                        *cpWrap = '\0';
+                        o = 1;
+                    }
+                    else {
+                        if ((cpWrap = (char *)realloc(cpWrap, strlen(cpWrap)+i+strlen(WRAPUSING)+1)) == NULL)
+                            return MSG_ERR_MEM;
+                        strcat(cpWrap, WRAPUSING);
+                    }
+                    strncat(cpWrap, cpCut, i);
+                }
             }
-            for (i = 0; i < strlen(cpRem) && ((cpRem[i] == ' ') || (cpRem[i] == '\t')); i++);
-            cpRem += i;
             if (strlen(cpRem) > 0) {
                 if ((cpWrap = (char *)realloc(cpWrap, strlen(cpWrap)+strlen(cpRem)+strlen(WRAPUSING)+1)) == NULL)
                         return MSG_ERR_MEM;
@@ -374,7 +381,7 @@
                                               str = "MSG: no description";
     if      (rc == MSG_OK                   ) str = "MSG: no error";
     else if (rc == MSG_ERR_MEM              ) str = "MSG: memory";
-    else if (rc == MSG_ERR_SPLITSPLITBODY   ) str = "MSG: split into header and body failed";
+    else if (rc == MSG_ERR_SPLITHEADBODY    ) str = "MSG: split into header and body failed";
     else if (rc == MSG_ERR_SPLITLEN         ) str = "MSG: header is too short";
     else if (rc == MSG_ERR_SPLITMISSINGFROM ) str = "MSG: header is missing 'From ' envelope";
     else if (rc == MSG_ERR_SPLITIDNONE      ) str = "MSG: header is missing 'Message-ID'";

CVSTrac 2.0.1