X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/6345e60c392bbf92b3d7ca2bba473f9da5c073ff..ddf3a8574f657dcb8c53fc5908e7bebbde1994b5:/uip/mhbuildsbr.c diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index d40d291a..b96e63ac 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -14,10 +14,27 @@ */ #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 "h/md5.h" #include "h/mts.h" #include "h/tws.h" #include "h/fmt_scan.h" @@ -25,7 +42,6 @@ #include "h/mhparse.h" #include "h/done.h" #include "h/utils.h" -#include "h/mhcachesbr.h" #include "mhmisc.h" #include "sbr/m_mktemp.h" #include "sbr/message_id.h" @@ -77,7 +93,6 @@ 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 **); @@ -175,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); @@ -186,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); @@ -350,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 @@ -1589,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: @@ -1764,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. @@ -1861,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