X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/29a1ada5b960fbf29d52e0f44911370a6c0c7c5f..ddf3a8574f657dcb8c53fc5908e7bebbde1994b5:/uip/mhbuildsbr.c diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index b8b28f24..b96e63ac 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -13,17 +13,35 @@ * streamlining and removal of unneeded code. */ -#include +#include "h/mh.h" +#include "sbr/m_gmprot.h" +#include "sbr/m_getfld.h" +#include "sbr/concat.h" +#include "sbr/r1bindex.h" +#include "sbr/encode_rfc2047.h" +#include "sbr/copyip.h" +#include "sbr/cpydata.h" +#include "sbr/trimcpy.h" +#include "sbr/uprf.h" +#include "sbr/check_charset.h" +#include "sbr/getcpy.h" +#include "sbr/m_convert.h" +#include "sbr/getfolder.h" +#include "sbr/folder_read.h" +#include "sbr/folder_free.h" +#include "sbr/context_find.h" +#include "sbr/brkstring.h" +#include "sbr/pidstatus.h" +#include "sbr/path.h" +#include "sbr/error.h" #include -#include -#include -#include -#include -#include -#include +#include "h/mts.h" +#include "h/tws.h" +#include "h/fmt_scan.h" +#include "h/mime.h" +#include "h/mhparse.h" #include "h/done.h" -#include -#include "h/mhcachesbr.h" +#include "h/utils.h" #include "mhmisc.h" #include "sbr/m_mktemp.h" #include "sbr/message_id.h" @@ -75,19 +93,20 @@ static void set_id (CT, int); static int compose_content (CT, int); static int scan_content (CT, size_t); static int build_headers (CT, int); -static char *calculate_digest (CT, int); static int extract_headers (CT, char *, FILE **); static unsigned char directives_stack[32]; static unsigned int directives_index; -static int do_direct(void) +static int +do_direct(void) { return directives_stack[directives_index]; } -static void directive_onoff(int onoff) +static void +directive_onoff(int onoff) { if (directives_index >= sizeof(directives_stack) - 1) { fprintf(stderr, "mhbuild: #on/off overflow, continuing\n"); @@ -96,13 +115,15 @@ static void directive_onoff(int onoff) directives_stack[++directives_index] = onoff; } -static void directive_init(int onoff) +static void +directive_init(int onoff) { directives_index = 0; directives_stack[0] = onoff; } -static void directive_pop(void) +static void +directive_pop(void) { if (directives_index > 0) directives_index--; @@ -169,9 +190,20 @@ build_mime (char *infile, int autobuild, int dist, int directives, case FLDPLUS: compnum++; - /* abort if draft has Mime-Version or C-T-E header field */ - if (strcasecmp (name, VRSN_FIELD) == 0 || - strcasecmp (name, ENCODING_FIELD) == 0) { + /* + * If we are running with autobuild set, then silently + * exit if we find a MIME-Version header. For any other MIME + * header, return an error. + * + * RFC 2045, Section 9 says that any valid MIME header should + * start with "Content-", so we will match on that rather than + * enumerate all current MIME headers. + * + * Because the headers could be in any order, just check for + * MIME-Version here; check for Content-* later. + */ + + if (strcasecmp (name, VRSN_FIELD) == 0) { if (autobuild) { fclose(in); free (ct); @@ -180,15 +212,6 @@ build_mime (char *infile, int autobuild, int dist, int directives, die("draft shouldn't contain %s: field", name); } - /* ignore any Content-Type fields in the header */ - if (!strcasecmp (name, TYPE_FIELD)) { - while (state == FLDPLUS) { - bufsz = sizeof buf; - state = m_getfld2(&gstate, name, buf, &bufsz); - } - goto finish_field; - } - /* get copies of the buffers */ np = mh_xstrdup(name); vp = mh_xstrdup(buf); @@ -344,6 +367,16 @@ finish_field: } m_getfld_state_destroy (&gstate); + /* + * If we see any Content-* headers at this point, it is an error. + */ + + for (hp = ct->c_first_hf; hp != NULL; hp = hp->next) { + if (uprf (hp->name, "Content-")) { + die ("draft shouldn't contain %s: field", hp->name); + } + } + if (header_encoding != CE_8BIT) { /* * Iterate through the list of headers and call the function to MIME-ify @@ -1583,7 +1616,7 @@ scan_content (CT ct, size_t maxunencoded) if (ct->c_reqencoding != CE_UNKNOWN) ct->c_encoding = ct->c_reqencoding; else { - int wants_q_p = (containsnul || linelen || linespace || checksw); + int wants_q_p = (containsnul || linelen || linespace); switch (ct->c_type) { case CT_TEXT: @@ -1758,15 +1791,6 @@ skip_headers: if (ct->c_ctexbody) return OK; - /* - * output the Content-MD5 - */ - if (checksw) { - np = mh_xstrdup(MD5_FIELD); - vp = calculate_digest (ct, ct->c_encoding == CE_QUOTED); - add_header (ct, np, vp); - } - /* * output the Content-Transfer-Encoding * If using EAI and message body is 7-bit, force 8-bit C-T-E. @@ -1855,101 +1879,6 @@ skip_headers: } -static char nib2b64[0x40+1] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static char * -calculate_digest (CT ct, int asciiP) -{ - int cc; - char *vp, *op; - unsigned char *dp; - unsigned char digest[16]; - unsigned char outbuf[25]; - MD5_CTX mdContext; - CE ce = &ct->c_cefile; - char *infilename = ce->ce_file ? ce->ce_file : ct->c_file; - FILE *in; - - /* open content */ - if ((in = fopen (infilename, "r")) == NULL) - adios (infilename, "unable to open for reading"); - - /* Initialize md5 context */ - MD5Init (&mdContext); - - /* calculate md5 message digest */ - if (asciiP) { - char *bufp = NULL; - size_t buflen; - ssize_t gotlen; - while ((gotlen = getline(&bufp, &buflen, in)) != -1) { - char c, *cp; - - cp = bufp + gotlen - 1; - if ((c = *cp) == '\n') - gotlen--; - - 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); - } - - /* md5 finalization. Write digest and zero md5 context */ - MD5Final (digest, &mdContext); - - /* close content */ - fclose (in); - - /* print debugging info */ - if (debugsw) { - unsigned char *ep; - - fprintf (stderr, "MD5 digest="); - for (ep = (dp = digest) + sizeof digest; - dp < ep; dp++) - fprintf (stderr, "%02x", *dp & 0xff); - fprintf (stderr, "\n"); - } - - /* encode the digest using base64 */ - for (dp = digest, op = (char *) outbuf, - cc = sizeof digest; - cc > 0; cc -= 3, op += 4) { - unsigned long bits; - char *bp; - - bits = (*dp++ & 0xff) << 16; - if (cc > 1) { - bits |= (*dp++ & 0xff) << 8; - if (cc > 2) - bits |= *dp++ & 0xff; - } - - for (bp = op + 4; bp > op; bits >>= 6) - *--bp = nib2b64[bits & 0x3f]; - if (cc < 3) { - *(op + 3) = '='; - if (cc < 2) - *(op + 2) = '='; - } - } - - /* null terminate string */ - outbuf[24] = '\0'; - - /* now make copy and return string */ - vp = concat (" ", outbuf, "\n", NULL); - return vp; -} - /* * Set things up for the content structure for file "filename" that * we want to attach @@ -2045,7 +1974,8 @@ setup_attach_content(CT ct, char *filename) * 'attachment'. */ void -set_disposition (CT ct) { +set_disposition (CT ct) +{ if (ct->c_dispo_type == NULL) { char *cp = context_find_by_type ("disposition", ct->c_ctinfo.ci_type, ct->c_ctinfo.ci_subtype); @@ -2075,7 +2005,8 @@ set_disposition (CT ct) { * -1: ignore content and use user's locale to determine charset */ void -set_charset (CT ct, int contains8bit) { +set_charset (CT ct, int contains8bit) +{ if (ct->c_type == CT_TEXT) { struct text *t; @@ -2114,7 +2045,8 @@ set_charset (CT ct, int contains8bit) { */ void expand_pseudoheaders (CT ct, struct multipart *m, const char *infile, - const convert_list *convert_head) { + const convert_list *convert_head) +{ /* text_plain_ct is used to concatenate all of the text/plain replies into one part, instead of having each one in a separate part. */ @@ -2190,7 +2122,8 @@ expand_pseudoheaders (CT ct, struct multipart *m, const char *infile, void expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m, const char *infile, const char *type, - const char *argstring) { + const char *argstring) +{ char *reply_file; FILE *reply_fp = NULL; char *convert, *type_p, *subtype_p; @@ -2339,7 +2272,8 @@ expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m, /* Extract any Content-Type header from beginning of convert output. */ int -extract_headers (CT ct, char *reply_file, FILE **reply_fp) { +extract_headers (CT ct, char *reply_file, FILE **reply_fp) +{ char *buffer = NULL, *cp, *end_of_header; bool found_header = false; struct stat statbuf;