X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/28c3595a77a8c942bee1057085776dad0b3d53f4..63621a81d16ab743de6b57d47578a9a2c670ad22:/uip/mhoutsbr.c diff --git a/uip/mhoutsbr.c b/uip/mhoutsbr.c index 9f024e08..4a3166f3 100644 --- a/uip/mhoutsbr.c +++ b/uip/mhoutsbr.c @@ -1,6 +1,4 @@ - -/* - * mhoutsbr.c -- routines to output MIME messages +/* mhoutsbr.c -- routines to output MIME messages * -- given a Content structure * * This code is Copyright (c) 2002, by the authors of nmh. See the @@ -10,20 +8,16 @@ #include #include -#include +#include #include #include #include #include #include +#include "mhoutsbr.h" +#include "sbr/base64.h" -/* - * prototypes - */ -int output_message (CT, char *); -int output_message_fp (CT, FILE *, char *); - /* * static prototypes */ @@ -54,23 +48,6 @@ output_message_fp (CT ct, FILE *fp, char *file) 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. @@ -97,7 +74,7 @@ output_content (CT ct, FILE *out) * headers (since it has no body). */ if (ct->c_ctexbody) { - if (boundary && *boundary != '\0') + if (*boundary != '\0') free(boundary); return OK; } @@ -117,7 +94,7 @@ output_content (CT ct, FILE *out) m = (struct multipart *) ct->c_ctparams; if (m->mp_content_before) { - fprintf (out, "%s", m->mp_content_before); + fputs(m->mp_content_before, out); } for (part = m->mp_parts; part; part = part->mp_next) { @@ -125,15 +102,15 @@ output_content (CT ct, FILE *out) fprintf (out, "\n--%s\n", boundary); if (output_content (p, out) == NOTOK) { - if (boundary && *boundary != '\0') + if (*boundary != '\0') free(boundary); - return NOTOK; + return NOTOK; } } fprintf (out, "\n--%s--\n", boundary); if (m->mp_content_after) { - fprintf (out, "%s", m->mp_content_after); + fputs(m->mp_content_after, out); } } break; @@ -165,7 +142,7 @@ output_content (CT ct, FILE *out) 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_first_pm != NULL || + if (ct->c_ctinfo.ci_first_pm != NULL || ct->c_begin == 0 || ct->c_begin != ct->c_end) { putc ('\n', out); } @@ -188,19 +165,25 @@ output_content (CT ct, FILE *out) break; case CE_BINARY: - advise (NULL, "can't handle binary transfer encoding in content"); - result = NOTOK; + if (ct->c_type == CT_TEXT) { + /* So that mhfixmsg can decode to binary text. */ + putc ('\n', out); + result = write8Bit (ct, out); + } else { + inform("can't handle binary transfer encoding in content"); + result = NOTOK; + } break; default: - advise (NULL, "unknown transfer encoding in content"); + inform("unknown transfer encoding in content"); result = NOTOK; break; } break; } - if (boundary && *boundary != '\0') + if (*boundary != '\0') free(boundary); return result; @@ -231,7 +214,7 @@ output_headers (CT ct, FILE *out) static int writeExternalBody (CT ct, FILE *out) { - char *cp; + char *cp, *dp; struct exbody *e = (struct exbody *) ct->c_ctparams; putc ('\n', out); @@ -243,7 +226,7 @@ writeExternalBody (CT ct, FILE *out) switch (*++cp) { case 'I': if (ct2->c_id) { - char *dp = trimcpy (ct2->c_id); + dp = trimcpy (ct2->c_id); fputs (dp, out); free (dp); @@ -251,21 +234,21 @@ writeExternalBody (CT ct, FILE *out) continue; case 'N': - cp = get_param(ci2->ci_first_pm, "name", '_', 0); - if (cp) { - fputs (cp, out); - free (cp); + dp = get_param(ci2->ci_first_pm, "name", '_', 0); + if (dp) { + fputs (dp, out); + free (dp); } continue; case 'T': fprintf (out, "%s/%s", ci2->ci_type, ci2->ci_subtype); - cp = output_params(strlen(ci2->ci_type) + + dp = output_params(strlen(ci2->ci_type) + strlen(ci2->ci_subtype) + 1, ci2->ci_first_pm, NULL, 0); - if (cp) { - fputs (cp, out); - free (cp); + if (dp) { + fputs (dp, out); + free (dp); } continue; @@ -317,7 +300,9 @@ write8Bit (CT ct, FILE *out) c = '\n'; while ((inbytes = fread (buffer, 1, sizeof buffer, ce->ce_fp)) > 0) { c = buffer[inbytes - 1]; - fwrite (buffer, 1, inbytes, out); + if (fwrite (buffer, 1, inbytes, out) < inbytes) { + advise ("write8Bit", "fwrite"); + } } if (c != '\n') putc ('\n', out); @@ -336,26 +321,35 @@ writeQuoted (CT ct, FILE *out) { int fd; char *cp, *file; - char c = '\0', buffer[BUFSIZ]; + char c = '\0'; CE ce = &ct->c_cefile; int n = 0; + char *bufp = NULL; + size_t buflen; + ssize_t gotlen; file = NULL; if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK) return NOTOK; - while (fgets (buffer, sizeof(buffer) - 1, ce->ce_fp)) { + while ((gotlen = getline(&bufp, &buflen, ce->ce_fp)) != -1) { - cp = buffer + strlen (buffer) - 1; + cp = bufp + gotlen - 1; if ((c = *cp) == '\n') - *cp = '\0'; - - if (strncmp (cp = buffer, "From ", sizeof("From ") - 1) == 0) { - fprintf (out, "=%02X", *cp++ & 0xff); + gotlen--; + + /* + * if the line starts with "From ", encode the 'F' so it + * doesn't falsely match an mbox delimiter. + */ + cp = bufp; + if (gotlen >= 5 && has_prefix(cp, "From ")) { + fprintf (out, "=%02X", 'F'); + cp++; n += 3; } - for (; *cp; cp++) { + for (; cp < bufp + gotlen; cp++) { if (n > CPERLIN - 3) { fputs ("=\n", out); n = 0; @@ -384,7 +378,7 @@ three_print: } if (c == '\n') { - if (cp > buffer && (*--cp == ' ' || *cp == '\t')) + if (cp > bufp && (*--cp == ' ' || *cp == '\t')) fputs ("=\n", out); putc ('\n', out); @@ -396,6 +390,7 @@ three_print: putc ('\n', out); (*ct->c_ceclosefnx) (ct); + free (bufp); return OK; } @@ -415,7 +410,10 @@ writeBase64ct (CT ct, FILE *out) if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK) return NOTOK; - result = writeBase64aux (ce->ce_fp, out, (ct->c_type == CT_TEXT)); + result = writeBase64aux (ce->ce_fp, out, + ct->c_type == CT_TEXT && ct->c_ctparams + ? ((struct text *) ct->c_ctparams)->lf_line_endings == 0 + : 0); (*ct->c_ceclosefnx) (ct); return result; }