X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/4885712264980e6cbc2039f9158027bee9213475..7559e1ebf:/uip/mhoutsbr.c?ds=inline diff --git a/uip/mhoutsbr.c b/uip/mhoutsbr.c index fff4ccc4..88f610dd 100644 --- a/uip/mhoutsbr.c +++ b/uip/mhoutsbr.c @@ -3,8 +3,6 @@ * 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. @@ -14,63 +12,17 @@ #include #include #include -#include -#include #include #include #include #include -#ifdef HAVE_SYS_WAIT_H -# include -#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 *); -int writeBase64aux (FILE *, FILE *); +int output_message_fp (CT, FILE *, char *); /* * 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 writeBase64 (CT, FILE *); +static int writeBase64ct (CT, FILE *); /* @@ -90,27 +42,35 @@ static int writeBase64 (CT, FILE *); */ 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)) { - advise (file, "error writing to"); + advise ((file?file:""), "error writing to"); return NOTOK; } - fclose (fp); - 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. @@ -121,6 +81,14 @@ output_content (CT ct, FILE *out) { 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 @@ -148,14 +116,23 @@ output_content (CT ct, FILE *out) 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; - fprintf (out, "\n--%s\n", ci->ci_values[0]); + fprintf (out, "\n--%s\n", boundary); 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; @@ -182,7 +159,14 @@ output_content (CT ct, FILE *out) 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; @@ -198,7 +182,7 @@ output_content (CT ct, FILE *out) case CE_BASE64: putc ('\n', out); - result = writeBase64 (ct, out); + result = writeBase64ct (ct, out); break; case CE_BINARY: @@ -312,17 +296,18 @@ static int write8Bit (CT ct, FILE *out) { int fd; + size_t inbytes; 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'; - 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); @@ -341,15 +326,15 @@ writeQuoted (CT ct, FILE *out) { 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)) { - int 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); - n = 3; - } else { - n = 0; + n += 3; } + for (; *cp; cp++) { if (n > CPERLIN - 3) { fputs ("=\n", out); @@ -375,8 +359,7 @@ writeQuoted (CT ct, FILE *out) break; default: - if (*cp < '!' || *cp > '~' - || (ebcdicsw && !ebcdicsafe[*cp & 0xff])) + if (*cp < '!' || *cp > '~') goto three_print; putc (*cp, out); n++; @@ -395,11 +378,13 @@ three_print: fputs ("=\n", out); putc ('\n', out); - } else { - fputs ("=\n", out); + n = 0; } } + if (c != '\n') + putc ('\n', out); + (*ct->c_ceclosefnx) (ct); return OK; } @@ -410,65 +395,17 @@ three_print: */ static int -writeBase64 (CT ct, FILE *out) +writeBase64ct (CT ct, FILE *out) { 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; - result = writeBase64aux (ce->ce_fp, out); + result = writeBase64aux (ce->ce_fp, out, (ct->c_type == CT_TEXT)); (*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; -}