]> diplodocus.org Git - nmh/blobdiff - uip/mhoutsbr.c
Migrated show_content_aux2() to argsplit().
[nmh] / uip / mhoutsbr.c
index fff4ccc420047244450405ba7c132ffdc097eed6..88f610dd0f54279b332a168206432c1f41e45ead 100644 (file)
@@ -3,8 +3,6 @@
  * mhoutsbr.c -- routines to output MIME messages
  *            -- given a Content structure
  *
  * mhoutsbr.c -- routines to output MIME messages
  *            -- given a Content structure
  *
- * $Id$
- *
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
  * complete copyright information.
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
  * complete copyright information.
 #include <fcntl.h>
 #include <h/signals.h>
 #include <h/md5.h>
 #include <fcntl.h>
 #include <h/signals.h>
 #include <h/md5.h>
-#include <errno.h>
-#include <signal.h>
 #include <h/mts.h>
 #include <h/tws.h>
 #include <h/mime.h>
 #include <h/mhparse.h>
 
 #include <h/mts.h>
 #include <h/tws.h>
 #include <h/mime.h>
 #include <h/mhparse.h>
 
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-
-extern int ebcdicsw;
-
-static char ebcdicsafe[0x100] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static char nib2b64[0x40+1] =
-       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 /*
  * prototypes
  */
 int output_message (CT, char *);
 
 /*
  * prototypes
  */
 int output_message (CT, char *);
-int writeBase64aux (FILE *, FILE *);
+int output_message_fp (CT, FILE *, char *);
 
 /*
  * static prototypes
 
 /*
  * static prototypes
@@ -80,7 +32,7 @@ static void output_headers (CT, FILE *);
 static int writeExternalBody (CT, FILE *);
 static int write8Bit (CT, FILE *);
 static int writeQuoted (CT, FILE *);
 static int writeExternalBody (CT, FILE *);
 static int write8Bit (CT, FILE *);
 static int writeQuoted (CT, FILE *);
-static int writeBase64 (CT, FILE *);
+static int writeBase64ct (CT, FILE *);
 
 
 /*
 
 
 /*
@@ -90,27 +42,35 @@ static int writeBase64 (CT, FILE *);
  */
 
 int
  */
 
 int
-output_message (CT ct, char *file)
+output_message_fp (CT ct, FILE *fp, char *file)
 {
 {
-    FILE *fp;
-
-    if ((fp = fopen (file, "w")) == NULL) {
-       advise (file, "unable to open for writing");
-       return NOTOK;
-    }
-
     if (output_content (ct, fp) == NOTOK)
        return NOTOK;
 
     if (fflush (fp)) {
     if (output_content (ct, fp) == NOTOK)
        return NOTOK;
 
     if (fflush (fp)) {
-       advise (file, "error writing to");
+       advise ((file?file:"<FILE*>"), "error writing to");
        return NOTOK;
     }
        return NOTOK;
     }
-    fclose (fp);
-
     return OK;
 }
 
     return OK;
 }
 
+int
+output_message (CT ct, char *file)
+{
+    FILE *fp;
+    int status;
+
+    if (! strcmp (file, "-")) {
+       fp = stdout;
+    } else if ((fp = fopen (file, "w")) == NULL) {
+       advise (file, "unable to open for writing");
+       return NOTOK;
+    }
+    status = output_message_fp(ct, fp, file);
+    if (strcmp (file, "-")) fclose(fp);
+    return status;
+}
+
 
 /*
  * Output a Content structure to a file.
 
 /*
  * Output a Content structure to a file.
@@ -121,6 +81,14 @@ output_content (CT ct, FILE *out)
 {
     int result = 0;
     CI ci = &ct->c_ctinfo;
 {
     int result = 0;
     CI ci = &ct->c_ctinfo;
+    char *boundary = ci->ci_values[0], **ap, **vp;
+
+    for (ap = ci->ci_attrs, vp = ci->ci_values; *ap; ++ap, ++vp) {
+        if (! strcasecmp ("boundary", *ap)) {
+            boundary = *vp;
+            break;
+        }
+    }
 
     /*
      * Output all header fields for this content
 
     /*
      * Output all header fields for this content
@@ -148,14 +116,23 @@ output_content (CT ct, FILE *out)
            putc ('\n', out);
 
        m = (struct multipart *) ct->c_ctparams;
            putc ('\n', out);
 
        m = (struct multipart *) ct->c_ctparams;
+
+        if (m->mp_content_before) {
+           fprintf (out, "%s", m->mp_content_before);
+        }
+
        for (part = m->mp_parts; part; part = part->mp_next) {
            CT p = part->mp_part;
 
        for (part = m->mp_parts; part; part = part->mp_next) {
            CT p = part->mp_part;
 
-           fprintf (out, "\n--%s\n", ci->ci_values[0]);
+           fprintf (out, "\n--%s\n", boundary);
            if (output_content (p, out) == NOTOK)
                return NOTOK;
        }
            if (output_content (p, out) == NOTOK)
                return NOTOK;
        }
-       fprintf (out, "\n--%s--\n", ci->ci_values[0]);
+       fprintf (out, "\n--%s--\n", boundary);
+
+        if (m->mp_content_after) {
+           fprintf (out, "%s", m->mp_content_after);
+        }
     }
     break;
 
     }
     break;
 
@@ -182,7 +159,14 @@ output_content (CT ct, FILE *out)
     default:
        switch (ct->c_encoding) {
        case CE_7BIT:
     default:
        switch (ct->c_encoding) {
        case CE_7BIT:
-           putc ('\n', out);
+           /* Special case:  if this is a non-MIME message with no
+              body, don't emit the newline that would appear between
+              the headers and body.  In that case, the call to
+              write8Bit() shouldn't be needed, but is harmless. */
+           if (ct->c_ctinfo.ci_attrs[0] != NULL  ||
+               ct->c_begin != ct->c_end) {
+               putc ('\n', out);
+           }
            result = write8Bit (ct, out);
            break;
 
            result = write8Bit (ct, out);
            break;
 
@@ -198,7 +182,7 @@ output_content (CT ct, FILE *out)
 
        case CE_BASE64:
            putc ('\n', out);
 
        case CE_BASE64:
            putc ('\n', out);
-           result = writeBase64 (ct, out);
+           result = writeBase64ct (ct, out);
            break;
 
        case CE_BINARY:
            break;
 
        case CE_BINARY:
@@ -312,17 +296,18 @@ static int
 write8Bit (CT ct, FILE *out)
 {
     int fd;
 write8Bit (CT ct, FILE *out)
 {
     int fd;
+    size_t inbytes;
     char c, *file, buffer[BUFSIZ];
     char c, *file, buffer[BUFSIZ];
-    CE ce = ct->c_cefile;
+    CE ce = &ct->c_cefile;
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
     c = '\n';
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
     c = '\n';
-    while (fgets (buffer, sizeof(buffer) - 1, ce->ce_fp)) {
-       c = buffer[strlen (buffer) - 1];
-       fputs (buffer, out);
+    while ((inbytes = fread (buffer, 1, sizeof buffer, ce->ce_fp)) > 0) {
+        c = buffer[inbytes - 1];
+        fwrite (buffer, 1, inbytes, out);
     }
     if (c != '\n')
        putc ('\n', out);
     }
     if (c != '\n')
        putc ('\n', out);
@@ -341,15 +326,15 @@ writeQuoted (CT ct, FILE *out)
 {
     int fd;
     char *cp, *file;
 {
     int fd;
     char *cp, *file;
-    char c, buffer[BUFSIZ];
-    CE ce = ct->c_cefile;
+    char c = '\0', buffer[BUFSIZ];
+    CE ce = &ct->c_cefile;
+    int n = 0;
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
     while (fgets (buffer, sizeof(buffer) - 1, ce->ce_fp)) {
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
     while (fgets (buffer, sizeof(buffer) - 1, ce->ce_fp)) {
-       int n;
 
        cp = buffer + strlen (buffer) - 1;
        if ((c = *cp) == '\n')
 
        cp = buffer + strlen (buffer) - 1;
        if ((c = *cp) == '\n')
@@ -357,10 +342,9 @@ writeQuoted (CT ct, FILE *out)
 
        if (strncmp (cp = buffer, "From ", sizeof("From ") - 1) == 0) {
            fprintf (out, "=%02X", *cp++ & 0xff);
 
        if (strncmp (cp = buffer, "From ", sizeof("From ") - 1) == 0) {
            fprintf (out, "=%02X", *cp++ & 0xff);
-           n = 3;
-       } else {
-           n = 0;
+           n += 3;
        }
        }
+
        for (; *cp; cp++) {
            if (n > CPERLIN - 3) {
                fputs ("=\n", out);
        for (; *cp; cp++) {
            if (n > CPERLIN - 3) {
                fputs ("=\n", out);
@@ -375,8 +359,7 @@ writeQuoted (CT ct, FILE *out)
                    break;
 
                default:
                    break;
 
                default:
-                   if (*cp < '!' || *cp > '~'
-                           || (ebcdicsw && !ebcdicsafe[*cp & 0xff]))
+                   if (*cp < '!' || *cp > '~')
                        goto three_print;
                    putc (*cp, out);
                    n++;
                        goto three_print;
                    putc (*cp, out);
                    n++;
@@ -395,11 +378,13 @@ three_print:
                fputs ("=\n", out);
 
            putc ('\n', out);
                fputs ("=\n", out);
 
            putc ('\n', out);
-       } else {
-           fputs ("=\n", out);
+           n = 0;
        }
     }
 
        }
     }
 
+    if (c != '\n')
+       putc ('\n', out);
+
     (*ct->c_ceclosefnx) (ct);
     return OK;
 }
     (*ct->c_ceclosefnx) (ct);
     return OK;
 }
@@ -410,65 +395,17 @@ three_print:
  */
 
 static int
  */
 
 static int
-writeBase64 (CT ct, FILE *out)
+writeBase64ct (CT ct, FILE *out)
 {
     int        fd, result;
     char *file;
 {
     int        fd, result;
     char *file;
-    CE ce = ct->c_cefile;
+    CE ce = &ct->c_cefile;
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
 
     file = NULL;
     if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
        return NOTOK;
 
-    result = writeBase64aux (ce->ce_fp, out);
+    result = writeBase64aux (ce->ce_fp, out, (ct->c_type == CT_TEXT));
     (*ct->c_ceclosefnx) (ct);
     return result;
 }
     (*ct->c_ceclosefnx) (ct);
     return result;
 }
-
-
-int
-writeBase64aux (FILE *in, FILE *out)
-{
-    int        cc, n;
-    char inbuf[3];
-
-    n = BPERLIN;
-    while ((cc = fread (inbuf, sizeof(*inbuf), sizeof(inbuf), in)) > 0) {
-       unsigned long bits;
-       char *bp;
-       char outbuf[4];
-
-       if (cc < sizeof(inbuf)) {
-           inbuf[2] = 0;
-           if (cc < sizeof(inbuf) - 1)
-               inbuf[1] = 0;
-       }
-       bits = (inbuf[0] & 0xff) << 16;
-       bits |= (inbuf[1] & 0xff) << 8;
-       bits |= inbuf[2] & 0xff;
-
-       for (bp = outbuf + sizeof(outbuf); bp > outbuf; bits >>= 6)
-           *--bp = nib2b64[bits & 0x3f];
-       if (cc < sizeof(inbuf)) {
-           outbuf[3] = '=';
-           if (cc < sizeof inbuf - 1)
-               outbuf[2] = '=';
-       }
-
-       fwrite (outbuf, sizeof(*outbuf), sizeof(outbuf), out);
-
-       if (cc < sizeof(inbuf)) {
-           putc ('\n', out);
-           return OK;
-       }
-
-       if (--n <= 0) {
-           n = BPERLIN;
-           putc ('\n', out);
-       }
-    }
-    if (n != BPERLIN)
-       putc ('\n', out);
-
-    return OK;
-}