]> diplodocus.org Git - nmh/blobdiff - uip/mhbuildsbr.c
mhn.defaults: make fetch less agressive on FreeBSD.
[nmh] / uip / mhbuildsbr.c
index dc0f407aef9c1dbe0ff41743b96fae91c1367ecd..68c555d36a2cf7b64804845153092fad56708cad 100644 (file)
@@ -173,6 +173,7 @@ build_mime (char *infile, int autobuild, int dist, int directives,
                strcasecmp (name, ENCODING_FIELD) == 0) {
                if (autobuild) {
                    fclose(in);
+                   free (ct);
                    return NULL;
                } else {
                    adios (NULL, "draft shouldn't contain %s: field", name);
@@ -398,7 +399,6 @@ finish_field:
        if ((part = (struct part *) calloc (1, sizeof(*part))) == NULL)
            adios (NULL, "out of memory");
        *pp = part;
-       pp = &part->mp_next;
        part->mp_part = p;
     }
 
@@ -780,7 +780,6 @@ use_forw:
                adios (NULL, "out of memory");
            init_decoded_content(ct, infilename);
            *ctp = ct;
-           ci = &ct->c_ctinfo;
            if (get_ctinfo (buffer, ct, 0) == NOTOK)
                done (1);
            ct->c_type = CT_MESSAGE;
@@ -827,14 +826,10 @@ use_forw:
         * No [file] argument, so check profile for
         * method to compose content.
         */
-       snprintf (buffer, sizeof(buffer), "%s-compose-%s/%s",
-               invo_name, ci->ci_type, ci->ci_subtype);
-       if ((cp = context_find (buffer)) == NULL || *cp == '\0') {
-           snprintf (buffer, sizeof(buffer), "%s-compose-%s", invo_name, ci->ci_type);
-           if ((cp = context_find (buffer)) == NULL || *cp == '\0') {
-               content_error (NULL, ct, "don't know how to compose content");
-               done (1);
-           }
+       cp = context_find_by_type ("compose", ci->ci_type, ci->ci_subtype);
+       if (cp == NULL) {
+           content_error (NULL, ct, "don't know how to compose content");
+           done (1);
        }
        ci->ci_magic = add (cp, NULL);
        return OK;
@@ -1480,9 +1475,16 @@ scan_content (CT ct, size_t maxunencoded)
        t = (struct text *) ct->c_ctparams;
        if (t->tx_charset == CHARSET_UNSPECIFIED) {
            CI ci = &ct->c_ctinfo;
+           char *eightbitcharset = write_charset_8bit();
+
+           if (contains8bit && strcasecmp(eightbitcharset, "US-ASCII") == 0) {
+               adios(NULL, "Text content contains 8 bit characters, but "
+                     "character set is US-ASCII");
+           }
 
            add_param(&ci->ci_first_pm, &ci->ci_last_pm, "charset",
-                       contains8bit ? write_charset_8bit() : "us-ascii", 0);
+                       contains8bit ? eightbitcharset : "us-ascii", 0);
+
            t->tx_charset = CHARSET_SPECIFIED;
        }
     }
@@ -1493,24 +1495,30 @@ scan_content (CT ct, size_t maxunencoded)
 
     if (ct->c_reqencoding != CE_UNKNOWN)
        ct->c_encoding = ct->c_reqencoding;
-    else
+    else {
+       int wants_q_p = (containsnul || linelen || linespace || checksw);
+
        switch (ct->c_type) {
        case CT_TEXT:
-           if (contains8bit && !containsnul && !linelen && !linespace && !checksw)
-               ct->c_encoding = CE_8BIT;
-           else if (contains8bit || containsnul || linelen || linespace || checksw)
-               ct->c_encoding = CE_QUOTED;
-           else
-               ct->c_encoding = CE_7BIT;
+            if (wants_q_p)
+                 ct->c_encoding = CE_QUOTED;
+            else if (contains8bit)
+                 ct->c_encoding = CE_8BIT;
+            else
+                 ct->c_encoding = CE_7BIT;
+
            break;
 
        case CT_APPLICATION:
            /* For application type, use base64, except when postscript */
-           if (containsnul || contains8bit || linelen || linespace || checksw)
-               ct->c_encoding = (ct->c_subtype == APPLICATION_POSTSCRIPT)
-                   ? CE_QUOTED : CE_BASE64;
-           else
+           if (wants_q_p || contains8bit) {
+               if (ct->c_subtype == APPLICATION_POSTSCRIPT)
+                   ct->c_encoding = CE_QUOTED;  /* historical */
+               else
+                   ct->c_encoding = CE_BASE64;
+           } else {
                ct->c_encoding = CE_7BIT;
+           }
            break;
 
        case CT_MESSAGE:
@@ -1524,6 +1532,7 @@ scan_content (CT ct, size_t maxunencoded)
            ct->c_encoding = CE_BASE64;
            break;
         }
+    }
 
     return (boundaryclash ? NOTOK : OK);
 }
@@ -1757,7 +1766,7 @@ static char *
 calculate_digest (CT ct, int asciiP)
 {
     int        cc;
-    char buffer[BUFSIZ], *vp, *op;
+    char *vp, *op;
     unsigned char *dp;
     unsigned char digest[16];
     unsigned char outbuf[25];
@@ -1775,20 +1784,24 @@ calculate_digest (CT ct, int asciiP)
 
     /* calculate md5 message digest */
     if (asciiP) {
-       while (fgets (buffer, sizeof(buffer) - 1, in)) {
+       char *bufp = NULL;
+       size_t buflen;
+       ssize_t gotlen;
+       while ((gotlen = getline(&bufp, &buflen, in)) != -1) {
            char c, *cp;
 
-           cp = buffer + strlen (buffer) - 1;
+           cp = bufp + gotlen - 1;
            if ((c = *cp) == '\n')
-               *cp = '\0';
+               gotlen--;
 
-           MD5Update (&mdContext, (unsigned char *) buffer,
-                      (unsigned int) strlen (buffer));
+           MD5Update (&mdContext, (unsigned char *) bufp,
+                      (unsigned int) gotlen);
 
            if (c == '\n')
                MD5Update (&mdContext, (unsigned char *) "\r\n", 2);
        }
     } else {
+       char buffer[BUFSIZ];
        while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), in)) > 0)
            MD5Update (&mdContext, (unsigned char *) buffer, (unsigned int) cc);
     }
@@ -1852,6 +1865,7 @@ setup_attach_content(CT ct, char *filename)
     char *type, *simplename = r1bindex(filename, '/');
     struct str2init *s2i;
     PM pm;
+    char *cp;
 
     if (! (type = mime_type(filename))) {
        adios(NULL, "Unable to determine MIME type of \"%s\"", filename);
@@ -1925,14 +1939,28 @@ setup_attach_content(CT ct, char *filename)
     ct->c_cefile.ce_file = getcpy(filename);
 
     /*
-     * If it's a text/calendar, we need to make sure it's an inline,
-     * otherwise it won't work with some calendar programs.  Otherwise
-     * assume attachment
+     * Look for mhbuild-disposition-<type>/<subtype> entry
+     * that specifies Content-Disposition type.  Only
+     * 'attachment' and 'inline' are allowed.  Default to
+     * 'attachment'.
      */
 
-    if (strcasecmp(ct->c_ctinfo.ci_type, "text") == 0 &&
-       strcasecmp(ct->c_ctinfo.ci_subtype, "calendar") == 0) {
-       ct->c_dispo_type = getcpy("inline");
+    cp = context_find_by_type ("disposition", ct->c_ctinfo.ci_type,
+                               ct->c_ctinfo.ci_subtype);
+    if (cp != NULL) {
+        if (strcasecmp (cp, "attachment")  &&  strcasecmp (cp, "inline")) {
+            admonish (NULL, "configuration problem: %s-disposition-%s%s%s "
+                      "specifies '%s' but only 'attachment' and 'inline' are "
+                      "allowed", invo_name,
+                      ct->c_ctinfo.ci_type,
+                      ct->c_ctinfo.ci_subtype ? "/" : "",
+                      ct->c_ctinfo.ci_subtype ? ct->c_ctinfo.ci_subtype : "",
+                      cp);
+        }
+    }
+
+    if (cp) {
+       ct->c_dispo_type = getcpy(cp);
     } else {
        ct->c_dispo_type = getcpy("attachment");
     }