-
/*
* mhoutsbr.c -- routines to output MIME messages
* -- given a Content structure
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
+ 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] =
int
output_message_fp (CT ct, FILE *fp, char *file)
{
- if (output_content (ct, fp) == NOTOK)
- return NOTOK;
-
- if (fflush (fp)) {
- advise ((file?file:"<FILE*>"), "error writing to");
- return NOTOK;
- }
- return OK;
+ if (output_content (ct, fp) == NOTOK)
+ return NOTOK;
+
+ if (fflush (fp)) {
+ advise ((file?file:"<FILE*>"), "error writing to");
+ return NOTOK;
+ }
+ return OK;
}
int
output_message (CT ct, char *file)
{
- FILE *fp;
- int status;
-
- if ((fp = fopen (file, "w")) == NULL) {
- advise (file, "unable to open for writing");
- return NOTOK;
- }
- status = output_message_fp(ct, fp, file);
- fclose(fp);
- return status;
+ FILE *fp;
+ int status;
+
+ if ((fp = fopen (file, "w")) == NULL) {
+ advise (file, "unable to open for writing");
+ return NOTOK;
+ }
+ status = output_message_fp(ct, fp, file);
+ fclose(fp);
+ return status;
}
static int
output_content (CT ct, FILE *out)
{
- int result = 0;
- CI ci = &ct->c_ctinfo;
-
- /*
- * Output all header fields for this content
- */
- output_headers (ct, out);
-
- /*
- * If this is the internal content structure for a
- * "message/external", then we are done with the
- * headers (since it has no body).
- */
- if (ct->c_ctexbody)
- return OK;
-
- /*
- * Now output the content bodies.
- */
- switch (ct->c_type) {
- case CT_MULTIPART:
- {
- struct multipart *m;
- struct part *part;
-
- if (ct->c_rfc934)
- putc ('\n', out);
+ int result = 0;
+ CI ci = &ct->c_ctinfo;
+
+ /*
+ * Output all header fields for this content
+ */
+ output_headers (ct, out);
+
+ /*
+ * If this is the internal content structure for a
+ * "message/external", then we are done with the
+ * headers (since it has no body).
+ */
+ if (ct->c_ctexbody)
+ return OK;
+
+ /*
+ * Now output the content bodies.
+ */
+ switch (ct->c_type) {
+ case CT_MULTIPART:
+ {
+ struct multipart *m;
+ struct part *part;
+
+ if (ct->c_rfc934)
+ putc ('\n', out);
+
+ m = (struct multipart *) ct->c_ctparams;
+ for (part = m->mp_parts; part; part = part->mp_next) {
+ CT p = part->mp_part;
+
+ fprintf (out, "\n--%s\n", ci->ci_values[0]);
+ if (output_content (p, out) == NOTOK)
+ return NOTOK;
+ }
+ fprintf (out, "\n--%s--\n", ci->ci_values[0]);
+ }
+ break;
- m = (struct multipart *) ct->c_ctparams;
- for (part = m->mp_parts; part; part = part->mp_next) {
- CT p = part->mp_part;
+ case CT_MESSAGE:
+ putc ('\n', out);
+ if (ct->c_subtype == MESSAGE_EXTERNAL) {
+ struct exbody *e;
+
+ e = (struct exbody *) ct->c_ctparams;
+ if (output_content (e->eb_content, out) == NOTOK)
+ return NOTOK;
+
+ /* output phantom body for access-type "mail-server" */
+ if (e->eb_body)
+ writeExternalBody (ct, out);
+ } else {
+ result = write8Bit (ct, out);
+ }
+ break;
- fprintf (out, "\n--%s\n", ci->ci_values[0]);
- if (output_content (p, out) == NOTOK)
- return NOTOK;
- }
- fprintf (out, "\n--%s--\n", ci->ci_values[0]);
- }
- break;
+ /*
+ * Handle discrete types (text/application/audio/image/video)
+ */
+ default:
+ switch (ct->c_encoding) {
+ case CE_7BIT:
+ putc ('\n', out);
+ result = write8Bit (ct, out);
+ break;
- case CT_MESSAGE:
- putc ('\n', out);
- if (ct->c_subtype == MESSAGE_EXTERNAL) {
- struct exbody *e;
+ case CE_8BIT:
+ putc ('\n', out);
+ result = write8Bit (ct, out);
+ break;
- e = (struct exbody *) ct->c_ctparams;
- if (output_content (e->eb_content, out) == NOTOK)
- return NOTOK;
+ case CE_QUOTED:
+ putc ('\n', out);
+ result = writeQuoted (ct, out);
+ break;
- /* output phantom body for access-type "mail-server" */
- if (e->eb_body)
- writeExternalBody (ct, out);
- } else {
- result = write8Bit (ct, out);
- }
- break;
+ case CE_BASE64:
+ putc ('\n', out);
+ result = writeBase64 (ct, out);
+ break;
- /*
- * Handle discrete types (text/application/audio/image/video)
- */
- default:
- switch (ct->c_encoding) {
- case CE_7BIT:
- putc ('\n', out);
- result = write8Bit (ct, out);
- break;
-
- case CE_8BIT:
- putc ('\n', out);
- result = write8Bit (ct, out);
- break;
-
- case CE_QUOTED:
- putc ('\n', out);
- result = writeQuoted (ct, out);
- break;
-
- case CE_BASE64:
- putc ('\n', out);
- result = writeBase64 (ct, out);
- break;
-
- case CE_BINARY:
- advise (NULL, "can't handle binary transfer encoding in content");
- result = NOTOK;
- break;
+ case CE_BINARY:
+ advise (NULL, "can't handle binary transfer encoding in content");
+ result = NOTOK;
+ break;
- default:
- advise (NULL, "unknown transfer encoding in content");
- result = NOTOK;
- break;
+ default:
+ advise (NULL, "unknown transfer encoding in content");
+ result = NOTOK;
+ break;
+ }
+ break;
}
- break;
- }
- return result;
+ return result;
}
static void
output_headers (CT ct, FILE *out)
{
- HF hp;
+ HF hp;
- hp = ct->c_first_hf;
- while (hp) {
- fprintf (out, "%s:%s", hp->name, hp->value);
- hp = hp->next;
- }
+ hp = ct->c_first_hf;
+ while (hp) {
+ fprintf (out, "%s:%s", hp->name, hp->value);
+ hp = hp->next;
+ }
}
static int
writeExternalBody (CT ct, FILE *out)
{
- char **ap, **ep, *cp;
- struct exbody *e = (struct exbody *) ct->c_ctparams;
-
- putc ('\n', out);
- for (cp = e->eb_body; *cp; cp++) {
- CT ct2 = e->eb_content;
- CI ci2 = &ct2->c_ctinfo;
-
- if (*cp == '\\') {
- switch (*++cp) {
- case 'I':
- if (ct2->c_id) {
- char *dp = trimcpy (ct2->c_id);
-
- fputs (dp, out);
- free (dp);
- }
- continue;
-
- case 'N':
- for (ap = ci2->ci_attrs, ep = ci2->ci_values; *ap; ap++, ep++)
- if (!mh_strcasecmp (*ap, "name")) {
- fprintf (out, "%s", *ep);
- break;
- }
- continue;
-
- case 'T':
- fprintf (out, "%s/%s", ci2->ci_type, ci2->ci_subtype);
- for (ap = ci2->ci_attrs, ep = ci2->ci_values; *ap; ap++, ep++)
- fprintf (out, "; %s=\"%s\"", *ap, *ep);
- continue;
+ char **ap, **ep, *cp;
+ struct exbody *e = (struct exbody *) ct->c_ctparams;
- case 'n':
- putc ('\n', out);
- continue;
-
- case 't':
- putc ('\t', out);
- continue;
-
- case '\0':
- cp--;
- break;
-
- case '\\':
- case '"':
- break;
-
- default:
- putc ('\\', out);
- break;
- }
+ putc ('\n', out);
+ for (cp = e->eb_body; *cp; cp++) {
+ CT ct2 = e->eb_content;
+ CI ci2 = &ct2->c_ctinfo;
+
+ if (*cp == '\\') {
+ switch (*++cp) {
+ case 'I':
+ if (ct2->c_id) {
+ char *dp = trimcpy (ct2->c_id);
+
+ fputs (dp, out);
+ free (dp);
+ }
+ continue;
+
+ case 'N':
+ for (ap = ci2->ci_attrs, ep = ci2->ci_values; *ap; ap++, ep++)
+ if (!mh_strcasecmp (*ap, "name")) {
+ fprintf (out, "%s", *ep);
+ break;
+ }
+ continue;
+
+ case 'T':
+ fprintf (out, "%s/%s", ci2->ci_type, ci2->ci_subtype);
+ for (ap = ci2->ci_attrs, ep = ci2->ci_values; *ap; ap++, ep++)
+ fprintf (out, "; %s=\"%s\"", *ap, *ep);
+ continue;
+
+ case 'n':
+ putc ('\n', out);
+ continue;
+
+ case 't':
+ putc ('\t', out);
+ continue;
+
+ case '\0':
+ cp--;
+ break;
+
+ case '\\':
+ case '"':
+ break;
+
+ default:
+ putc ('\\', out);
+ break;
+ }
+ }
+ putc (*cp, out);
}
- putc (*cp, out);
- }
- putc ('\n', out);
+ putc ('\n', out);
- return OK;
+ return OK;
}
static int
write8Bit (CT ct, FILE *out)
{
- int fd;
- char c, *file, buffer[BUFSIZ];
- 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);
- }
- if (c != '\n')
- putc ('\n', out);
+ int fd;
+ char c, *file, buffer[BUFSIZ];
+ 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);
+ }
+ if (c != '\n')
+ putc ('\n', out);
- (*ct->c_ceclosefnx) (ct);
- return OK;
+ (*ct->c_ceclosefnx) (ct);
+ return OK;
}
static int
writeQuoted (CT ct, FILE *out)
{
- int fd;
- char *cp, *file;
- char c, buffer[BUFSIZ];
- CE ce = ct->c_cefile;
-
- 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 = '\0';
-
- if (strncmp (cp = buffer, "From ", sizeof("From ") - 1) == 0) {
- fprintf (out, "=%02X", *cp++ & 0xff);
- n = 3;
- } else {
- n = 0;
- }
- for (; *cp; cp++) {
- if (n > CPERLIN - 3) {
- fputs ("=\n", out);
- n = 0;
- }
-
- switch (*cp) {
- case ' ':
- case '\t':
- putc (*cp, out);
- n++;
- break;
+ int fd;
+ char *cp, *file;
+ char c, buffer[BUFSIZ];
+ CE ce = ct->c_cefile;
- default:
- if (*cp < '!' || *cp > '~'
- || (ebcdicsw && !ebcdicsafe[*cp & 0xff]))
- goto three_print;
- putc (*cp, out);
- n++;
- break;
-
- case '=':
+ 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 = '\0';
+
+ if (strncmp (cp = buffer, "From ", sizeof("From ") - 1) == 0) {
+ fprintf (out, "=%02X", *cp++ & 0xff);
+ n = 3;
+ } else {
+ n = 0;
+ }
+ for (; *cp; cp++) {
+ if (n > CPERLIN - 3) {
+ fputs ("=\n", out);
+ n = 0;
+ }
+
+ switch (*cp) {
+ case ' ':
+ case '\t':
+ putc (*cp, out);
+ n++;
+ break;
+
+ default:
+ if (*cp < '!' || *cp > '~'
+ || (ebcdicsw && !ebcdicsafe[*cp & 0xff]))
+ goto three_print;
+ putc (*cp, out);
+ n++;
+ break;
+
+ case '=':
three_print:
- fprintf (out, "=%02X", *cp & 0xff);
- n += 3;
- break;
- }
- }
+ fprintf (out, "=%02X", *cp & 0xff);
+ n += 3;
+ break;
+ }
+ }
- if (c == '\n') {
- if (cp > buffer && (*--cp == ' ' || *cp == '\t'))
- fputs ("=\n", out);
+ if (c == '\n') {
+ if (cp > buffer && (*--cp == ' ' || *cp == '\t'))
+ fputs ("=\n", out);
- putc ('\n', out);
- } else {
- fputs ("=\n", out);
+ putc ('\n', out);
+ } else {
+ fputs ("=\n", out);
+ }
}
- }
- (*ct->c_ceclosefnx) (ct);
- return OK;
+ (*ct->c_ceclosefnx) (ct);
+ return OK;
}
static int
writeBase64 (CT ct, FILE *out)
{
- int fd, result;
- char *file;
- CE ce = ct->c_cefile;
+ int fd, result;
+ char *file;
+ 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);
- (*ct->c_ceclosefnx) (ct);
- return result;
+ result = writeBase64aux (ce->ce_fp, out);
+ (*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] = '=';
- }
+ 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);
+ fwrite (outbuf, sizeof(*outbuf), sizeof(outbuf), out);
- if (cc < sizeof(inbuf)) {
- putc ('\n', out);
- return OK;
- }
+ if (cc < sizeof(inbuf)) {
+ putc ('\n', out);
+ return OK;
+ }
- if (--n <= 0) {
- n = BPERLIN;
- putc ('\n', out);
+ if (--n <= 0) {
+ n = BPERLIN;
+ putc ('\n', out);
+ }
}
- }
- if (n != BPERLIN)
- putc ('\n', out);
+ if (n != BPERLIN)
+ putc ('\n', out);
- return OK;
+ return OK;
}