* streamlining and removal of unneeded code.
*/
-#include <h/mh.h>
+#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 <fcntl.h>
-#include <h/md5.h>
-#include <h/mts.h>
-#include <h/tws.h>
-#include <h/fmt_scan.h>
-#include <h/mime.h>
-#include <h/mhparse.h>
+#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 <h/utils.h>
-#include "h/mhcachesbr.h"
+#include "h/utils.h"
#include "mhmisc.h"
#include "sbr/m_mktemp.h"
#include "sbr/message_id.h"
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");
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--;
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);
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);
}
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
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:
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.
}
-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