]> diplodocus.org Git - nmh/blobdiff - uip/mhbuildsbr.c
Deference char pointer to test for empty string instead of strlen(3).
[nmh] / uip / mhbuildsbr.c
index 26d8524d767a9f72005a641924ce4e2325135d57..eca264c887ea16b58421735ee622fceff2648c02 100644 (file)
@@ -161,8 +161,7 @@ build_mime (char *infile, int autobuild, int dist, int directives,
     /*
      * Allocate space for primary (outside) content
      */
-    if ((ct = (CT) mh_xcalloc (1, sizeof(*ct))) == NULL)
-       adios (NULL, "out of memory");
+    NEW0(ct);
 
     /*
      * Allocate structure for handling decoded content
@@ -244,7 +243,7 @@ build_mime (char *infile, int autobuild, int dist, int directives,
                    goto finish_field;
                }
 
-               entry = mh_xmalloc(sizeof(*entry));
+               NEW(entry);
                entry->filename = getcpy(s);
                entry->next = NULL;
                free(vp);
@@ -281,7 +280,7 @@ build_mime (char *infile, int autobuild, int dist, int directives,
                         convert->filename = getcpy (filename);
                     }
                 } else {
-                    convert = mh_xcalloc (sizeof *convert, 1);
+                    NEW0(convert);
                     convert->filename = getcpy (filename);
                     convert->type = getcpy (type);
 
@@ -321,7 +320,7 @@ build_mime (char *infile, int autobuild, int dist, int directives,
                         convert->argstring = getcpy (argstring);
                     }
                 } else {
-                    convert = mh_xcalloc (sizeof *convert, 1);
+                    NEW0(convert);
                     convert->type = getcpy (type);
                     convert->argstring = getcpy (argstring);
 
@@ -394,8 +393,7 @@ finish_field:
     ct->c_type = CT_MULTIPART;
     ct->c_subtype = MULTI_MIXED;
 
-    if ((m = (struct multipart *) mh_xcalloc (1, sizeof(*m))) == NULL)
-       adios (NULL, "out of memory");
+    NEW0(m);
     ct->c_ctparams = (void *) m;
     pp = &m->mp_parts;
 
@@ -414,8 +412,7 @@ finish_field:
        if (!p)
            continue;
 
-       if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
-           adios (NULL, "out of memory");
+       NEW0(part);
        *pp = part;
        pp = &part->mp_next;
        part->mp_part = p;
@@ -435,9 +432,7 @@ finish_field:
            adios("reading", "Unable to open %s for", at_entry->filename);
        }
 
-       if ((p = (CT) mh_xcalloc (1, sizeof(*p))) == NULL)
-           adios(NULL, "out of memory");
-
+       NEW0(p);
        init_decoded_content(p, infile);
 
        /*
@@ -448,8 +443,7 @@ finish_field:
 
        setup_attach_content(p, at_entry->filename);
 
-       if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
-           adios (NULL, "out of memory");
+       NEW0(part);
        *pp = part;
        pp = &part->mp_next;
        part->mp_part = p;
@@ -474,9 +468,8 @@ finish_field:
         free (cts);
 
         /* Extract the type part (as a CT) from filename. */
-        if (! (cts = (CT *) mh_xcalloc ((size_t) 2, sizeof *cts))) {
-            adios (NULL, "out of memory");
-        } else if (! (cts[0] = parse_mime (convert_head->filename))) {
+        cts = mh_xcalloc(2, sizeof *cts);
+        if (! (cts[0] = parse_mime (convert_head->filename))) {
             adios (NULL, "failed to parse %s", convert_head->filename);
         }
 
@@ -503,9 +496,7 @@ finish_field:
        struct part *part;
        struct text *t;
 
-       if ((p = (CT) mh_xcalloc (1, sizeof(*p))) == NULL)
-           adios(NULL, "out of memory");
-
+       NEW0(p);
        init_decoded_content(p, infile);
 
        if (get_ctinfo ("text/plain", p, 0) == NOTOK)
@@ -519,18 +510,15 @@ finish_field:
         * So this seems like the best option available since we're going
         * to call scan_content() on this.
         */
-       p->c_cefile.ce_file = getcpy("/dev/null");
+       p->c_cefile.ce_file = mh_xstrdup("/dev/null");
        p->c_begin = ftell(in);
        p->c_end = ftell(in);
 
-       if ((t = (struct text *) mh_xcalloc (1, sizeof (*t))) == NULL)
-           adios (NULL, "out of memory");
-
+       NEW0(t);
        t->tx_charset = CHARSET_SPECIFIED;
        p->c_ctparams = t;
 
-       if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
-           adios (NULL, "out of memory");
+       NEW0(part);
        *pp = part;
        part->mp_part = p;
     }
@@ -677,8 +665,7 @@ user_content (FILE *in, char *buf, CT *ctp, const char *infilename)
     }
 
     /* allocate basic Content structure */
-    if ((ct = (CT) mh_xcalloc (1, sizeof(*ct))) == NULL)
-       adios (NULL, "out of memory");
+    NEW0(ct);
     *ctp = ct;
 
     /* allocate basic structure for handling decoded content */
@@ -909,8 +896,7 @@ use_forw:
             * reference, we need to create another Content structure
             * for the message/external-body to wrap it in.
             */
-           if ((ct = (CT) mh_xcalloc (1, sizeof(*ct))) == NULL)
-               adios (NULL, "out of memory");
+           NEW0(ct);
            init_decoded_content(ct, infilename);
            *ctp = ct;
            if (get_ctinfo (buffer, ct, 0) == NOTOK)
@@ -918,8 +904,7 @@ use_forw:
            ct->c_type = CT_MESSAGE;
            ct->c_subtype = MESSAGE_EXTERNAL;
 
-           if ((e = (struct exbody *) mh_xcalloc (1, sizeof(*e))) == NULL)
-               adios (NULL, "out of memory");
+           NEW0(e);
            ct->c_ctparams = (void *) e;
 
            e->eb_parent = ct;
@@ -1028,8 +1013,7 @@ use_forw:
            ct->c_type = CT_MULTIPART;
            ct->c_subtype = MULTI_DIGEST;
 
-           if ((m = (struct multipart *) mh_xcalloc (1, sizeof(*m))) == NULL)
-               adios (NULL, "out of memory");
+           NEW0(m);
            ct->c_ctparams = (void *) m;
            pp = &m->mp_parts;
 
@@ -1039,8 +1023,7 @@ use_forw:
                    CT p;
                    CE pe;
 
-                   if ((p = (CT) mh_xcalloc (1, sizeof(*p))) == NULL)
-                       adios (NULL, "out of memory");
+                   NEW0(p);
                    init_decoded_content (p, infilename);
                    pe = &p->c_cefile;
                    if (get_ctinfo ("message/rfc822", p, 0) == NOTOK)
@@ -1053,8 +1036,7 @@ use_forw:
                    if (listsw && stat (pe->ce_file, &st) != NOTOK)
                        p->c_end = (long) st.st_size;
 
-                   if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
-                       adios (NULL, "out of memory");
+                   NEW0(part);
                    *pp = part;
                    pp = &part->mp_next;
                    part->mp_part = p;
@@ -1114,8 +1096,7 @@ use_forw:
        ct->c_type = CT_MULTIPART;
        ct->c_subtype = vrsn;
 
-       if ((m = (struct multipart *) mh_xcalloc (1, sizeof(*m))) == NULL)
-           adios (NULL, "out of memory");
+       NEW0(m);
        ct->c_ctparams = (void *) m;
 
        pp = &m->mp_parts;
@@ -1131,8 +1112,7 @@ use_forw:
            if (!p)
                continue;
 
-           if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
-               adios (NULL, "out of memory");
+           NEW0(part);
            *pp = part;
            pp = &part->mp_next;
            part->mp_part = p;
@@ -1453,15 +1433,17 @@ scan_content (CT ct, size_t maxunencoded)
      * Decide what to check while scanning this content.  Note that
      * for text content we always check for 8bit characters if the
      * charset is unspecified, because that controls whether or not the
-     * character set is us-ascii or retrieved from the locale.
+     * character set is us-ascii or retrieved from the locale.  And
+     * we check even if the charset is specified, to allow setting
+     * the proper Content-Transfer-Encoding.
      */
 
     if (ct->c_type == CT_TEXT) {
        t = (struct text *) ct->c_ctparams;
        if (t->tx_charset == CHARSET_UNSPECIFIED) {
-           check8bit = 1;
            checknul = 1;
        }
+       check8bit = 1;
     }
 
     switch (ct->c_reqencoding) {
@@ -2085,7 +2067,7 @@ set_disposition (CT ct) {
                       cp);
         }
 
-        ct->c_dispo_type = cp  ?  getcpy (cp)  :  getcpy ("attachment");
+        ct->c_dispo_type = cp  ?  getcpy (cp) : mh_xstrdup("attachment");
     }
 }
 
@@ -2102,11 +2084,8 @@ set_charset (CT ct, int contains8bit) {
         struct text *t;
 
         if (ct->c_ctparams == NULL) {
-            if ((t = ct->c_ctparams =
-                 (struct text *) mh_xcalloc (1, sizeof (struct text))) ==
-                NULL) {
-                adios (NULL, "out of memory");
-            }
+            NEW0(t);
+            ct->c_ctparams = t;
             t->tx_charset = CHARSET_UNSPECIFIED;
         } else {
             t = (struct text *) ct->c_ctparams;
@@ -2225,6 +2204,7 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     struct str2init *s2i;
     CT reply_ct;
     struct part *part;
+    int eightbit = 0;
     int status;
 
     type_p = getcpy (type);
@@ -2260,7 +2240,7 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     free (convert_command);
 
     /* Fill out the the new ct, reply_ct. */
-    reply_ct = (CT) mh_xcalloc (1, sizeof *reply_ct);
+    NEW0(reply_ct);
     init_decoded_content (reply_ct, infile);
 
     if (extract_headers (reply_ct, reply_file, &reply_fp) == NOTOK) {
@@ -2271,6 +2251,20 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
         return;
     }
 
+    /* For text content only, see if it is 8-bit text. */
+    if (reply_ct->c_type == CT_TEXT) {
+        int fd;
+
+        if ((fd = open (reply_file, O_RDONLY)) == NOTOK  ||
+            scan_input (fd, &eightbit) == NOTOK) {
+            free (reply_file);
+            admonish (NULL, "failed to read %s", reply_file);
+            return;
+        } else {
+            (void) close (fd);
+        }
+    }
+
     /* This sets reply_ct->c_ctparams, and reply_ct->c_termproc if the
        charset can't be handled natively. */
     for (s2i = str2cts; s2i->si_key; s2i++) {
@@ -2290,10 +2284,15 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     } else {
         set_charset (reply_ct, -1);
         charset = get_param (reply_ct->c_ctinfo.ci_first_pm, "charset", '?', 1);
-        if (reply_ct->c_reqencoding == CE_UNKNOWN) {
-            /* Assume that 8bit is sufficient (for text). */
-            reply_ct->c_reqencoding =
-                strcasecmp (charset, "US-ASCII")  ?  CE_8BIT  :  CE_7BIT;
+        if (reply_ct->c_reqencoding == CE_UNKNOWN  &&
+            reply_ct->c_type == CT_TEXT) {
+            /* Assume that 8bit is sufficient (for text).  In other words,
+               don't allow it to be encoded as quoted printable if lines
+               are too long.  This also sidesteps the check for whether
+               it needs to be encoded as binary; instead, it relies on
+               the applicable mhbuild-convert-text directive to ensure
+               that the resultant text is not binary. */
+            reply_ct->c_reqencoding = eightbit  ?  CE_8BIT  :  CE_7BIT;
         }
     }
 
@@ -2308,9 +2307,14 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
                part. */
             set_charset (*text_plain_ct, -1);
             if ((*text_plain_ct)->c_reqencoding == CE_UNKNOWN) {
-                /* Assume that 8bit is sufficient (for text). */
+                /* Assume that 8bit is sufficient (for text).  In other words,
+                   don't allow it to be encoded as quoted printable if lines
+                   are too long.  This also sidesteps the check for whether
+                   it needs to be encoded as binary; instead, it relies on
+                   the applicable mhbuild-convert-text directive to ensure
+                   that the resultant text is not binary. */
                 (*text_plain_ct)->c_reqencoding =
-                    strcasecmp (charset, "US-ASCII")  ?  CE_8BIT  :  CE_7BIT;
+                    eightbit  ?  CE_8BIT  :  CE_7BIT;
             }
         }
 
@@ -2340,6 +2344,13 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
                                  reply_file);
                         if (close (text_plain_reply) == OK  &&
                             close (addl_reply) == OK) {
+                            /* If appended text needed 8-bit but first text didn't,
+                               propagate the 8-bit indication. */
+                            if ((*text_plain_ct)->c_reqencoding == CE_7BIT  &&
+                                reply_ct->c_reqencoding == CE_8BIT) {
+                                (*text_plain_ct)->c_reqencoding = CE_8BIT;
+                            }
+
                             if (reply_fp) { fclose (reply_fp); }
                             free (reply_file);
                             free_content (reply_ct);
@@ -2357,8 +2368,8 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
     reply_ct->c_cefile.ce_fp = reply_fp;
     reply_ct->c_cefile.ce_unlink = 1;
 
-    /* Attach the new part to the parent mulitpart/mixed, "m". */
-    part = (struct part *) mh_xcalloc (1, sizeof *part);
+    /* Attach the new part to the parent multipart/mixed, "m". */
+    NEW0(part);
     part->mp_part = reply_ct;
     if (m->mp_parts) {
         struct part *p;