X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/6f9d27d45bd1ba8299ed15d53cdb76a365d641c5..8aeb28b95bce93b69967f612ee437b66b61a332b:/uip/mhparse.c diff --git a/uip/mhparse.c b/uip/mhparse.c index 94fd50bc..cb9d2799 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -5,27 +5,38 @@ * complete copyright information. */ -#include +#include "h/mh.h" +#include "sbr/m_gmprot.h" +#include "sbr/m_getfld.h" +#include "sbr/read_yes_or_no_if_tty.h" +#include "sbr/concat.h" +#include "sbr/r1bindex.h" +#include "sbr/ruserpass.h" +#include "sbr/fmt_rfc2047.h" +#include "sbr/uprf.h" +#include "sbr/check_charset.h" +#include "sbr/getcpy.h" +#include "sbr/context_find.h" +#include "sbr/pidstatus.h" +#include "sbr/arglist.h" +#include "sbr/error.h" #include -#include -#include -#include -#include -#include -#include +#include "h/mts.h" +#include "h/tws.h" +#include "h/mime.h" +#include "h/mhparse.h" +#include "h/utils.h" #include "mhmisc.h" -#include -#include "../sbr/m_mktemp.h" +#include "sbr/m_mktemp.h" #include "mhfree.h" #ifdef HAVE_ICONV # include #endif /* HAVE_ICONV */ +#include "sbr/base64.h" extern int debugsw; -int checksw = 0; /* check Content-MD5 field */ - /* * These are for mhfixmsg to: * 1) Instruct parser not to detect invalid Content-Transfer-Encoding @@ -45,8 +56,7 @@ bool suppress_extraneous_trailing_semicolon_warning; bool suppress_multiple_mime_version_warning = true; /* list of preferred type/subtype pairs, for -prefer */ -char *preferred_types[NPREFS]; -char *preferred_subtypes[NPREFS]; +mime_type_subtype mime_preference[NPREFS]; int npreferred; @@ -79,7 +89,6 @@ struct k2v SubMultiPart[] = { */ struct k2v SubMessage[] = { { "rfc822", MESSAGE_RFC822 }, - { "partial", MESSAGE_PARTIAL }, { "external-body", MESSAGE_EXTERNAL }, { NULL, MESSAGE_UNKNOWN } /* this one must be last! */ }; @@ -127,14 +136,13 @@ static int openBase64 (CT, char **); static int InitQuoted (CT); static int openQuoted (CT, char **); static int Init7Bit (CT); -static int openExternal (CT, CT, CE, char **, int *); +static int openExternal (CT, CE, char **, int *); static int InitFile (CT); static int openFile (CT, char **); static int InitFTP (CT); static int openFTP (CT, char **); static int InitMail (CT); static int openMail (CT, char **); -static int readDigest (CT, char *); static int get_leftover_mp_content (CT, int); static int InitURL (CT); static int openURL (CT, char **); @@ -361,10 +369,10 @@ get_content (FILE *in, char *file, int toplevel) case LENERR: case FMTERR: - adios (NULL, "message format error in component #%d", compnum); + die("message format error in component #%d", compnum); default: - adios (NULL, "getfld() returned %d", state); + die("getfld() returned %d", state); } /* break out of the loop */ @@ -495,46 +503,6 @@ get_content (FILE *in, char *file, int toplevel) if (s2i->si_init && (*s2i->si_init) (ct) == NOTOK) goto out; } - else if (!strcasecmp (hp->name, MD5_FIELD)) { - /* Get Content-MD5 field */ - char *cp, *dp, *ep; - - if (!checksw) - goto next_header; - - if (ct->c_digested) { - inform("message %s has multiple %s: fields", - ct->c_file, MD5_FIELD); - goto next_header; - } - - ep = cp = mh_xstrdup(FENDNULL(hp->value)); /* get a copy */ - - while (isspace ((unsigned char) *cp)) - cp++; - for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n')) - *dp++ = ' '; - for (dp = cp + strlen (cp) - 1; dp >= cp; dp--) - if (!isspace ((unsigned char) *dp)) - break; - *++dp = '\0'; - if (debugsw) - fprintf (stderr, "%s: %s\n", MD5_FIELD, cp); - - if (*cp == '(' && - get_comment (ct->c_file, MD5_FIELD, &cp, NULL) == NOTOK) { - free (ep); - goto out; - } - - for (dp = cp; *dp && !isspace ((unsigned char) *dp); dp++) - continue; - *dp = '\0'; - - readDigest (ct, cp); - free (ep); - ct->c_digested++; - } else if (!strcasecmp (hp->name, ID_FIELD)) { /* Get Content-ID field */ ct->c_id = add (hp->value, ct->c_id); @@ -657,7 +625,7 @@ get_ctinfo (char *cp, CT ct, int magic) fprintf (stderr, "%s: %s\n", TYPE_FIELD, cp); if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp, - &ci->ci_comment) == NOTOK) + &ci->ci_comment) == NOTOK) return NOTOK; for (dp = cp; istoken (*dp); dp++) @@ -679,7 +647,7 @@ get_ctinfo (char *cp, CT ct, int magic) cp++; if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp, - &ci->ci_comment) == NOTOK) + &ci->ci_comment) == NOTOK) return NOTOK; if (*cp != '/') { @@ -693,7 +661,7 @@ get_ctinfo (char *cp, CT ct, int magic) cp++; if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp, - &ci->ci_comment) == NOTOK) + &ci->ci_comment) == NOTOK) return NOTOK; for (dp = cp; istoken (*dp); dp++) @@ -716,11 +684,11 @@ magic_skip: cp++; if (*cp == '(' && get_comment (ct->c_file, TYPE_FIELD, &cp, - &ci->ci_comment) == NOTOK) + &ci->ci_comment) == NOTOK) return NOTOK; if ((status = parse_header_attrs (ct->c_file, TYPE_FIELD, &cp, - &ci->ci_first_pm, &ci->ci_last_pm, + &ci->ci_first_pm, &ci->ci_last_pm, &ci->ci_comment)) != OK) { return status == NOTOK ? NOTOK : OK; } @@ -729,7 +697,7 @@ magic_skip: * Get any given in buffer */ if (magic && *cp == '<') { - mh_xfree(ct->c_id); + free(ct->c_id); ct->c_id = NULL; if (!(dp = strchr(ct->c_id = ++cp, '>'))) { inform("invalid ID in message %s", ct->c_file); @@ -808,7 +776,7 @@ magic_skip: */ if (magic && *cp == '*') { - /* + /* * See if it's a CTE we match on */ struct k2v *kv; @@ -906,7 +874,7 @@ get_dispo (char *cp, CT ct, int buildflag) fprintf (stderr, "%s: %s\n", DISPO_FIELD, cp); if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) == - NOTOK) { + NOTOK) { free(dispoheader); return NOTOK; } @@ -923,7 +891,7 @@ get_dispo (char *cp, CT ct, int buildflag) return NOTOK; if ((status = parse_header_attrs (ct->c_file, DISPO_FIELD, &cp, - &ct->c_dispo_first, &ct->c_dispo_last, + &ct->c_dispo_first, &ct->c_dispo_last, NULL)) != OK) { if (status == NOTOK) { free(dispoheader); @@ -935,7 +903,7 @@ get_dispo (char *cp, CT ct, int buildflag) } if (buildflag) - free(dispoheader); + free(dispoheader); else ct->c_dispo = dispoheader; @@ -1082,7 +1050,7 @@ InitText (CT ct) static int InitMultiPart (CT ct) { - int inout; + bool inout; long last, pos; char *cp, *dp; PM pm; @@ -1108,7 +1076,7 @@ InitMultiPart (CT ct) bp = cte + strlen (cte) - 1; while (bp >= cte && isspace ((unsigned char) *bp)) *bp-- = '\0'; - for (bp = cte; *bp && isblank ((unsigned char) *bp); ++bp) continue; + for (bp = cte; isblank((unsigned char)*bp); ++bp) continue; inform("\"%s/%s\" type in message %s must be encoded in\n" "7bit, 8bit, or binary, per RFC 2045 (6.4). " @@ -1175,7 +1143,7 @@ InitMultiPart (CT ct) last = ct->c_end; next = &m->mp_parts; part = NULL; - inout = 1; + inout = true; while ((gotlen = getline(&bufp, &buflen, fp)) != -1) { if (pos > last) @@ -1184,6 +1152,23 @@ InitMultiPart (CT ct) pos += gotlen; if (bufp[0] != '-' || bufp[1] != '-') continue; + + /* + * A bit of a lame hack; if this line ends in \r\n then replace + * the \r\n with just a \n so that the boundary markers will match + * up properly in case this uses "MS-DOS" line endings. + */ + + if (gotlen > 2 && bufp[gotlen - 1] == '\n' && + bufp[gotlen - 2] == '\r') { + /* + * Note we don't change getpos here, because it is used to + * calculate multipart offsets. + */ + bufp[gotlen - 2] = '\n'; + bufp[gotlen - 1] = '\0'; + } + if (inout) { if (strcmp (bufp + 2, m->mp_start)) continue; @@ -1202,10 +1187,10 @@ next_part: part->mp_part = p; pos = p->c_begin; fseek (fp, pos, SEEK_SET); - inout = 0; + inout = false; } else { if (strcmp (bufp + 2, m->mp_start) == 0) { - inout = 1; + inout = true; end_part: p = part->mp_part; p->c_end = ftell(fp) - (gotlen + 1); @@ -1316,7 +1301,7 @@ reverse_parts (CT ct) } static void -move_preferred_part (CT ct, char *type, char *subtype) +move_preferred_part(CT ct, mime_type_subtype *pref) { struct multipart *m = (struct multipart *) ct->c_ctparams; struct part *part, *prev, *head, *nhead, *ntail; @@ -1340,8 +1325,9 @@ move_preferred_part (CT ct, char *type, char *subtype) part = head->mp_next; while (part != NULL) { ci = &part->mp_part->c_ctinfo; - if (!strcasecmp(ci->ci_type, type) && - (!subtype || !strcasecmp(ci->ci_subtype, subtype))) { + if (!strcasecmp(ci->ci_type, pref->type) && + (!pref->subtype || + !strcasecmp(ci->ci_subtype, pref->subtype))) { prev->mp_next = part->mp_next; part->mp_next = NULL; ntail->mp_next = part; @@ -1354,7 +1340,6 @@ move_preferred_part (CT ct, char *type, char *subtype) } ntail->mp_next = head->mp_next; m->mp_parts = nhead->mp_next; - } /* @@ -1366,8 +1351,8 @@ static void prefer_parts(CT ct) { int i; - for (i = npreferred-1; i >= 0; i--) - move_preferred_part(ct, preferred_types[i], preferred_subtypes[i]); + for (i = 0; i < npreferred; i++) + move_preferred_part(ct, mime_preference + i); } @@ -1377,7 +1362,8 @@ prefer_parts(CT ct) example, a text/plain part before a text/html part in a multipart/alternative part, for example, where it belongs. */ void -reverse_alternative_parts (CT ct) { +reverse_alternative_parts (CT ct) +{ if (ct->c_type == CT_MULTIPART) { struct multipart *m = (struct multipart *) ct->c_ctparams; struct part *part; @@ -1421,49 +1407,6 @@ InitMessage (CT ct) case MESSAGE_RFC822: break; - case MESSAGE_PARTIAL: - { - PM pm; - struct partial *p; - - NEW0(p); - ct->c_ctparams = (void *) p; - - /* scan for parameters "id", "number", and "total" */ - for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) { - if (!strcasecmp (pm->pm_name, "id")) { - p->pm_partid = mh_xstrdup(FENDNULL(pm->pm_value)); - continue; - } - if (!strcasecmp (pm->pm_name, "number")) { - if (sscanf (pm->pm_value, "%d", &p->pm_partno) != 1 - || p->pm_partno < 1) { -invalid_param: - inform("invalid %s parameter for \"%s/%s\" type in message %s's %s field", - pm->pm_name, ci->ci_type, ci->ci_subtype, - ct->c_file, TYPE_FIELD); - return NOTOK; - } - continue; - } - if (!strcasecmp (pm->pm_name, "total")) { - if (sscanf (pm->pm_value, "%d", &p->pm_maxno) != 1 - || p->pm_maxno < 1) - goto invalid_param; - continue; - } - } - - if (!p->pm_partid - || !p->pm_partno - || (p->pm_maxno && p->pm_partno > p->pm_maxno)) { - inform("invalid parameters for \"%s/%s\" type in message %s's %s field", - ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD); - return NOTOK; - } - } - break; - case MESSAGE_EXTERNAL: { int exresult; @@ -1511,7 +1454,7 @@ invalid_param: adios ("failed", "fread"); case OK: - adios (NULL, "unexpected EOF from fread"); + die("unexpected EOF from fread"); default: bp += cc, size -= cc; @@ -1629,7 +1572,7 @@ params_external (CT ct, int composing) e->eb_url = u = mh_xmalloc(strlen(pm->pm_value) + 1); for (; *p != '\0'; p++) { - if (! isspace((unsigned char) *p)) + if (! isspace((unsigned char) *p)) *u++ = *p; } @@ -1714,11 +1657,11 @@ size_encoding (CT ct) } if (ct->c_encoding == CE_EXTERNAL) - return (ct->c_end - ct->c_begin); + return ct->c_end - ct->c_begin; file = NULL; if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK) - return (ct->c_end - ct->c_begin); + return ct->c_end - ct->c_begin; if (fstat (fd, &st) != NOTOK) size = (long) st.st_size; @@ -1745,14 +1688,14 @@ static int openBase64 (CT ct, char **file) { ssize_t cc, len; - int fd, own_ct_fp = 0; + int fd; + bool own_ct_fp = false; char *cp, *buffer = NULL; /* sbeck -- handle suffixes */ CI ci; CE ce = &ct->c_cefile; unsigned char *decoded; size_t decoded_len; - unsigned char digest[16]; if (ce->ce_fp) { fseek (ce->ce_fp, 0L, SEEK_SET); @@ -1780,7 +1723,7 @@ openBase64 (CT ct, char **file) if (ce->ce_unlink) { /* Create temporary file with filename extension. */ if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } } else { @@ -1789,7 +1732,7 @@ openBase64 (CT ct, char **file) } else if (*file == NULL) { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); @@ -1801,7 +1744,7 @@ openBase64 (CT ct, char **file) } if ((len = ct->c_end - ct->c_begin) < 0) - adios (NULL, "internal error(1)"); + die("internal error(1)"); buffer = mh_xmalloc (len + 1); @@ -1810,7 +1753,7 @@ openBase64 (CT ct, char **file) content_error (ct->c_file, ct, "unable to open for reading"); return NOTOK; } - own_ct_fp = 1; + own_ct_fp = true; } lseek (fd = fileno (ct->c_fp), (off_t) ct->c_begin, SEEK_SET); @@ -1836,8 +1779,8 @@ openBase64 (CT ct, char **file) /* decodeBase64() requires null-terminated input. */ *cp = '\0'; - if (decodeBase64 (buffer, &decoded, &decoded_len, ct->c_type == CT_TEXT, - ct->c_digested ? digest : NULL) != OK) + if (decodeBase64 (buffer, &decoded, &decoded_len, + ct->c_type == CT_TEXT) != OK) goto clean_up; { @@ -1851,18 +1794,6 @@ openBase64 (CT ct, char **file) content_error (ce->ce_file, ct, "error writing to"); goto clean_up; } - - if (ct->c_digested) { - if (memcmp(digest, ct->c_digest, - sizeof digest)) { - content_error (NULL, ct, - "content integrity suspect (digest mismatch) -- continuing"); - } else { - if (debugsw) { - fprintf (stderr, "content integrity confirmed\n"); - } - } - } } fseek (ct->c_fp, 0L, SEEK_SET); @@ -1928,7 +1859,8 @@ InitQuoted (CT ct) static int openQuoted (CT ct, char **file) { - int cc, digested, len, quoted, own_ct_fp = 0; + int cc, len, quoted; + bool own_ct_fp = false; char *cp, *ep; char *bufp = NULL; size_t buflen; @@ -1937,7 +1869,6 @@ openQuoted (CT ct, char **file) CE ce = &ct->c_cefile; /* sbeck -- handle suffixes */ CI ci; - MD5_CTX mdContext; if (ce->ce_fp) { fseek (ce->ce_fp, 0L, SEEK_SET); @@ -1965,7 +1896,7 @@ openQuoted (CT ct, char **file) if (ce->ce_unlink) { /* Create temporary file with filename extension. */ if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } } else { @@ -1974,7 +1905,7 @@ openQuoted (CT ct, char **file) } else if (*file == NULL) { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); @@ -1986,23 +1917,17 @@ openQuoted (CT ct, char **file) } if ((len = ct->c_end - ct->c_begin) < 0) - adios (NULL, "internal error(2)"); + die("internal error(2)"); if (! ct->c_fp) { if ((ct->c_fp = fopen (ct->c_file, "r")) == NULL) { content_error (ct->c_file, ct, "unable to open for reading"); return NOTOK; } - own_ct_fp = 1; + own_ct_fp = true; } - if ((digested = ct->c_digested)) - MD5Init (&mdContext); - quoted = 0; -#ifdef lint - mask = 0; -#endif fseek (ct->c_fp, ct->c_begin, SEEK_SET); while (len > 0) { @@ -2034,8 +1959,6 @@ openQuoted (CT ct, char **file) mask <<= 4; mask |= hex2nib[((unsigned char) *cp) & 0x7f]; putc (mask, ce->ce_fp); - if (digested) - MD5Update (&mdContext, &mask, 1); if (ferror (ce->ce_fp)) { content_error (ce->ce_file, ct, "error writing to"); goto clean_up; @@ -2073,13 +1996,6 @@ openQuoted (CT ct, char **file) /* Just show the raw byte. */ putc (*cp, ce->ce_fp); - if (digested) { - if (*cp == '\n') { - MD5Update (&mdContext, (unsigned char *) "\r\n",2); - } else { - MD5Update (&mdContext, (unsigned char *) cp, 1); - } - } if (ferror (ce->ce_fp)) { content_error (ce->ce_file, ct, "error writing to"); goto clean_up; @@ -2099,18 +2015,6 @@ openQuoted (CT ct, char **file) goto clean_up; } - if (digested) { - unsigned char digest[16]; - - MD5Final (digest, &mdContext); - if (memcmp((char *) digest, (char *) ct->c_digest, - sizeof digest)) - content_error (NULL, ct, - "content integrity suspect (digest mismatch) -- continuing"); - else if (debugsw) - fprintf (stderr, "content integrity confirmed\n"); - } - fseek (ce->ce_fp, 0L, SEEK_SET); ready_to_go: @@ -2151,7 +2055,8 @@ Init7Bit (CT ct) int open7Bit (CT ct, char **file) { - int cc, fd, len, own_ct_fp = 0; + int cc, fd, len; + bool own_ct_fp = false; char buffer[BUFSIZ]; /* sbeck -- handle suffixes */ char *cp; @@ -2184,7 +2089,7 @@ open7Bit (CT ct, char **file) if (ce->ce_unlink) { /* Create temporary file with filename extension. */ if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } } else { @@ -2193,7 +2098,7 @@ open7Bit (CT ct, char **file) } else if (*file == NULL) { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); @@ -2242,14 +2147,14 @@ open7Bit (CT ct, char **file) } if ((len = ct->c_end - ct->c_begin) < 0) - adios (NULL, "internal error(3)"); + die("internal error(3)"); if (! ct->c_fp) { if ((ct->c_fp = fopen (ct->c_file, "r")) == NULL) { content_error (ct->c_file, ct, "unable to open for reading"); return NOTOK; } - own_ct_fp = 1; + own_ct_fp = true; } lseek (fd = fileno (ct->c_fp), (off_t) ct->c_begin, SEEK_SET); @@ -2309,10 +2214,8 @@ clean_up: */ static int -openExternal (CT ct, CT cb, CE ce, char **file, int *fd) +openExternal (CT ct, CE ce, char **file, int *fd) { - char cachefile[BUFSIZ]; - if (ce->ce_fp) { fseek (ce->ce_fp, 0L, SEEK_SET); goto ready_already; @@ -2326,16 +2229,6 @@ openExternal (CT ct, CT cb, CE ce, char **file, int *fd) goto ready_already; } - if (find_cache (ct, rcachesw, (int *) 0, cb->c_id, - cachefile, sizeof(cachefile)) != NOTOK) { - if ((ce->ce_fp = fopen (cachefile, "r"))) { - ce->ce_file = mh_xstrdup(cachefile); - ce->ce_unlink = 0; - goto ready_already; - } - admonish (cachefile, "unable to fopen for reading"); - } - *fd = ce->ce_fp ? fileno (ce->ce_fp) : -1; return OK; @@ -2359,12 +2252,11 @@ InitFile (CT ct) static int openFile (CT ct, char **file) { - int fd, cachetype; - char cachefile[BUFSIZ]; + int fd; struct exbody *e = ct->c_ctexbody; CE ce = &ct->c_cefile; - switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) { + switch (openExternal (e->eb_parent, ce, file, &fd)) { case NOTOK: return NOTOK; @@ -2388,39 +2280,6 @@ openFile (CT ct, char **file) return NOTOK; } - if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write")) - && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id, - cachefile, sizeof(cachefile)) != NOTOK) { - int mask; - FILE *fp; - - mask = umask (cachetype ? ~m_gmprot () : 0222); - if ((fp = fopen (cachefile, "w"))) { - int cc; - char buffer[BUFSIZ]; - FILE *gp = ce->ce_fp; - - fseek (gp, 0L, SEEK_SET); - - while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp)) - > 0) - if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) { - advise ("openFile", "fwrite"); - } - fflush (fp); - - if (ferror (gp)) { - admonish (ce->ce_file, "error reading"); - (void) m_unlink (cachefile); - } else if (ferror (fp)) { - admonish (cachefile, "error writing"); - (void) m_unlink (cachefile); - } - fclose (fp); - } - umask (mask); - } - fseek (ce->ce_fp, 0L, SEEK_SET); *file = ce->ce_file; return fileno (ce->ce_fp); @@ -2440,10 +2299,10 @@ InitFTP (CT ct) static int openFTP (CT ct, char **file) { - int cachetype, caching, fd; + int fd; int len, buflen; char *bp, *ftp, *user, *pass; - char buffer[BUFSIZ], cachefile[BUFSIZ]; + char buffer[BUFSIZ]; struct exbody *e; CE ce = &ct->c_cefile; static char *username = NULL; @@ -2457,7 +2316,7 @@ openFTP (CT ct, char **file) if (!ftp) return NOTOK; - switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) { + switch (openExternal (e->eb_parent, ce, file, &fd)) { case NOTOK: return NOTOK; @@ -2515,7 +2374,7 @@ openFTP (CT ct, char **file) if (e->eb_flags) { user = "anonymous"; - snprintf (buffer, sizeof(buffer), "%s@%s", getusername (), + snprintf (buffer, sizeof(buffer), "%s@%s", getusername (1), LocalName (1)); pass = buffer; } else { @@ -2525,25 +2384,13 @@ openFTP (CT ct, char **file) } ce->ce_unlink = (*file == NULL); - caching = 0; - cachefile[0] = '\0'; - if ((!e->eb_permission || strcasecmp (e->eb_permission, "read-write")) - && find_cache (NULL, wcachesw, &cachetype, e->eb_content->c_id, - cachefile, sizeof(cachefile)) != NOTOK) { - if (*file == NULL) { - ce->ce_unlink = 0; - caching = 1; - } - } if (*file) ce->ce_file = mh_xstrdup(*file); - else if (caching) - ce->ce_file = mh_xstrdup(cachefile); else { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); @@ -2555,7 +2402,7 @@ openFTP (CT ct, char **file) } { - int child_id, i, vecp; + int child_id, vecp; char *vec[9]; vecp = 0; @@ -2567,13 +2414,12 @@ openFTP (CT ct, char **file) vec[vecp++] = e->eb_name; vec[vecp++] = ce->ce_file, vec[vecp++] = e->eb_mode && !strcasecmp (e->eb_mode, "ascii") - ? "ascii" : "binary"; + ? "ascii" : "binary"; vec[vecp] = NULL; fflush (stdout); - for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) - sleep (5); + child_id = fork(); switch (child_id) { case NOTOK: adios ("fork", "unable to"); @@ -2584,7 +2430,7 @@ openFTP (CT ct, char **file) execvp (ftp, vec); fprintf (stderr, "unable to exec "); perror (ftp); - _exit (-1); + _exit(1); /* NOTREACHED */ default: @@ -2597,40 +2443,6 @@ openFTP (CT ct, char **file) } } - if (cachefile[0]) { - if (caching) - chmod (cachefile, cachetype ? m_gmprot () : 0444); - else { - int mask; - FILE *fp; - - mask = umask (cachetype ? ~m_gmprot () : 0222); - if ((fp = fopen (cachefile, "w"))) { - int cc; - FILE *gp = ce->ce_fp; - - fseek (gp, 0L, SEEK_SET); - - while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp)) - > 0) - if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) { - advise ("openFTP", "fwrite"); - } - fflush (fp); - - if (ferror (gp)) { - admonish (ce->ce_file, "error reading"); - (void) m_unlink (cachefile); - } else if (ferror (fp)) { - admonish (cachefile, "error writing"); - (void) m_unlink (cachefile); - } - fclose (fp); - } - umask (mask); - } - } - fseek (ce->ce_fp, 0L, SEEK_SET); *file = ce->ce_file; return fileno (ce->ce_fp); @@ -2651,13 +2463,13 @@ InitMail (CT ct) static int openMail (CT ct, char **file) { - int child_id, fd, i, vecp; + int child_id, fd, vecp; int len, buflen; char *bp, buffer[BUFSIZ], *vec[7]; struct exbody *e = ct->c_ctexbody; CE ce = &ct->c_cefile; - switch (openExternal (e->eb_parent, e->eb_content, ce, file, &fd)) { + switch (openExternal (e->eb_parent, ce, file, &fd)) { case NOTOK: return NOTOK; @@ -2707,8 +2519,7 @@ openMail (CT ct, char **file) vec[vecp++] = e->eb_body; vec[vecp] = NULL; - for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) - sleep (5); + child_id = fork(); switch (child_id) { case NOTOK: advise ("fork", "unable to"); @@ -2718,7 +2529,7 @@ openMail (CT ct, char **file) execvp (mailproc, vec); fprintf (stderr, "unable to exec "); perror (mailproc); - _exit (-1); + _exit(1); /* NOTREACHED */ default: @@ -2730,7 +2541,7 @@ openMail (CT ct, char **file) if (*file == NULL) { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); @@ -2747,7 +2558,7 @@ openMail (CT ct, char **file) /* showproc is for mhshow and mhstore, though mhlist -debug * prints it, too. */ - mh_xfree(ct->c_showproc); + free(ct->c_showproc); ct->c_showproc = mh_xstrdup("true"); fseek (ce->ce_fp, 0L, SEEK_SET); @@ -2773,21 +2584,20 @@ openURL (CT ct, char **file) struct exbody *e = ct->c_ctexbody; CE ce = &ct->c_cefile; char *urlprog, *program; - char buffer[BUFSIZ], cachefile[BUFSIZ]; - int fd, caching, cachetype; + int fd; struct msgs_array args = { 0, 0, NULL}; pid_t child_id; if ((urlprog = context_find(nmhaccessurl)) && *urlprog == '\0') - urlprog = NULL; + urlprog = NULL; if (! urlprog) { - content_error(NULL, ct, "No entry for nmh-access-url in profile"); - return NOTOK; + content_error(NULL, ct, "No entry for nmh-access-url in profile"); + return NOTOK; } - switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) { - case NOTOK: + switch (openExternal(e->eb_parent, ce, file, &fd)) { + case NOTOK: return NOTOK; case OK: @@ -2798,47 +2608,35 @@ openURL (CT ct, char **file) } if (!e->eb_url) { - content_error(NULL, ct, "missing url parameter"); + content_error(NULL, ct, "missing url parameter"); return NOTOK; } ce->ce_unlink = (*file == NULL); - caching = 0; - cachefile[0] = '\0'; - - if (find_cache(NULL, wcachesw, &cachetype, e->eb_content->c_id, - cachefile, sizeof(cachefile)) != NOTOK) { - if (*file == NULL) { - ce->ce_unlink = 0; - caching = 1; - } - } if (*file) ce->ce_file = mh_xstrdup(*file); - else if (caching) - ce->ce_file = mh_xstrdup(cachefile); else { char *tempfile; if ((tempfile = m_mktemp2(NULL, invo_name, NULL, NULL)) == NULL) { - adios(NULL, "unable to create temporary file in %s", + die("unable to create temporary file in %s", get_temp_dir()); } ce->ce_file = mh_xstrdup(tempfile); } if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) { - content_error(ce->ce_file, ct, "unable to fopen for read/writing"); + content_error(ce->ce_file, ct, "unable to fopen for read/writing"); return NOTOK; } switch (child_id = fork()) { case NOTOK: - adios ("fork", "unable to"); + adios ("fork", "unable to"); /* NOTREACHED */ case OK: - argsplit_msgarg(&args, urlprog, &program); + argsplit_msgarg(&args, urlprog, &program); app_msgarg(&args, e->eb_url); app_msgarg(&args, NULL); dup2(fileno(ce->ce_fp), 1); @@ -2846,93 +2644,22 @@ openURL (CT ct, char **file) execvp(program, args.msgs); fprintf(stderr, "Unable to exec "); perror(program); - _exit(-1); + _exit(1); /* NOTREACHED */ default: - if (pidXwait(child_id, NULL)) { + if (pidXwait(child_id, NULL)) { ce->ce_unlink = 1; return NOTOK; } } - if (cachefile[0]) { - if (caching) - chmod(cachefile, cachetype ? m_gmprot() : 0444); - else { - int mask; - FILE *fp; - - mask = umask (cachetype ? ~m_gmprot() : 0222); - if ((fp = fopen(cachefile, "w"))) { - int cc; - FILE *gp = ce->ce_fp; - - fseeko(gp, 0, SEEK_SET); - - while ((cc = fread(buffer, sizeof(*buffer), - sizeof(buffer), gp)) > 0) - if ((int) fwrite(buffer, sizeof(*buffer), cc, fp) < cc) { - advise ("openURL", "fwrite"); - } - - fflush(fp); - - if (ferror(gp)) { - admonish(ce->ce_file, "error reading"); - (void) m_unlink (cachefile); - } - } - umask(mask); - } - } - fseeko(ce->ce_fp, 0, SEEK_SET); *file = ce->ce_file; return fileno(ce->ce_fp); } -/* - * Stores MD5 digest (in cp, from Content-MD5 header) in ct->c_digest. It - * has to be base64 decoded. - */ -static int -readDigest (CT ct, char *cp) -{ - unsigned char *digest; - - size_t len; - if (decodeBase64 (cp, &digest, &len, 0, NULL) == OK) { - const size_t maxlen = sizeof ct->c_digest; - - if (strlen ((char *) digest) <= maxlen) { - memcpy (ct->c_digest, digest, maxlen); - - if (debugsw) { - size_t i; - - fprintf (stderr, "MD5 digest="); - for (i = 0; i < maxlen; ++i) { - fprintf (stderr, "%02x", ct->c_digest[i] & 0xff); - } - fprintf (stderr, "\n"); - } - - return OK; - } - if (debugsw) { - fprintf (stderr, "invalid MD5 digest (got %d octets)\n", - (int) strlen ((char *) digest)); - } - - return NOTOK; - } - - return NOTOK; -} - - /* Multipart parts might have content before the first subpart and/or after the last subpart that hasn't been stored anywhere else, so do that. */ @@ -2941,7 +2668,7 @@ get_leftover_mp_content (CT ct, int before /* or after */) { struct multipart *m = (struct multipart *) ct->c_ctparams; char *boundary; - int found_boundary = 0; + bool found_boundary = false; int max = BUFSIZ; char *bufp = NULL; size_t buflen; @@ -2986,11 +2713,11 @@ get_leftover_mp_content (CT ct, int before /* or after */) if (before) { if (! strcmp (bufp, boundary)) { - found_boundary = 1; + found_boundary = true; } } else { if (! found_boundary && ! strcmp (bufp, boundary)) { - found_boundary = 1; + found_boundary = true; continue; } } @@ -3044,7 +2771,8 @@ get_leftover_mp_content (CT ct, int before /* or after */) char * -ct_type_str (int type) { +ct_type_str (int type) +{ switch (type) { case CT_APPLICATION: return "application"; @@ -3069,7 +2797,8 @@ ct_type_str (int type) { char * -ct_subtype_str (int type, int subtype) { +ct_subtype_str (int type, int subtype) +{ switch (type) { case CT_APPLICATION: switch (subtype) { @@ -3084,8 +2813,6 @@ ct_subtype_str (int type, int subtype) { switch (subtype) { case MESSAGE_RFC822: return "rfc822"; - case MESSAGE_PARTIAL: - return "partial"; case MESSAGE_EXTERNAL: return "external"; default: @@ -3124,7 +2851,8 @@ ct_subtype_str (int type, int subtype) { int -ct_str_type (const char *type) { +ct_str_type (const char *type) +{ struct str2init *s2i; for (s2i = str2cts; s2i->si_key; ++s2i) { @@ -3141,7 +2869,8 @@ ct_str_type (const char *type) { int -ct_str_subtype (int type, const char *subtype) { +ct_str_subtype (int type, const char *subtype) +{ struct k2v *kv; switch (type) { @@ -3181,7 +2910,8 @@ ct_str_subtype (int type, const char *subtype) { /* Find the content type and InitFunc for the CT. */ const struct str2init * -get_ct_init (int type) { +get_ct_init (int type) +{ const struct str2init *sp; for (sp = str2cts; sp->si_key; ++sp) { @@ -3194,7 +2924,8 @@ get_ct_init (int type) { } const char * -ce_str (int encoding) { +ce_str (int encoding) +{ switch (encoding) { case CE_BASE64: return "base64"; @@ -3217,7 +2948,8 @@ ce_str (int encoding) { /* Find the content type and InitFunc for the content encoding method. */ const struct str2init * -get_ce_method (const char *method) { +get_ce_method (const char *method) +{ struct str2init *sp; for (sp = str2ces; sp->si_key; ++sp) { @@ -3271,7 +3003,9 @@ parse_header_attrs (const char *filename, const char *fieldname, while (*cp == ';') { char *dp, *vp, *up, *nameptr, *valptr, *charset = NULL, *lang = NULL; - int encoded = 0, partial = 0, len = 0, index = 0; + bool encoded = false; + bool partial = false; + int len = 0, index = 0; cp++; while (isspace ((unsigned char) *cp)) @@ -3321,11 +3055,11 @@ parse_header_attrs (const char *filename, const char *fieldname, for (vp = cp; vp < up; vp++) { if (*vp == '*' && vp < up - 1) { - partial = 1; + partial = true; continue; } if (*vp == '*' && vp == up - 1) { - encoded = 1; + encoded = true; } else if (partial) { if (isdigit((unsigned char) *vp)) index = *vp - '0' + index * 10; @@ -3358,7 +3092,7 @@ parse_header_attrs (const char *filename, const char *fieldname, * parameter). */ if (index == 0) { - vp = dp; + vp = dp; while (*vp != '\'' && !isspace((unsigned char) *vp) && *vp != '\0') vp++; @@ -3398,7 +3132,7 @@ parse_header_attrs (const char *filename, const char *fieldname, inform("missing language tag in message %s's %s: field\n" " (parameter %s)", filename, fieldname, nameptr); free(nameptr); - mh_xfree(charset); + free(charset); return NOTOK; } @@ -3421,8 +3155,8 @@ parse_header_attrs (const char *filename, const char *fieldname, inform("invalid encoded sequence in message %s's %s: field\n" " (parameter %s)", filename, fieldname, nameptr); free(nameptr); - mh_xfree(charset); - mh_xfree(lang); + free(charset); + free(lang); return NOTOK; } vp += 2; @@ -3462,8 +3196,8 @@ bad_quote: inform("invalid quoted-string in message %s's %s: field\n" " (parameter %s)", filename, fieldname, nameptr); free(nameptr); - mh_xfree(charset); - mh_xfree(lang); + free(charset); + free(lang); return NOTOK; case '"': break; @@ -3488,7 +3222,7 @@ bad_quote: valptr = mh_xmalloc(len + 1); if (*dp == '"') { - int i; + int i; for (cp = dp + 1, vp = valptr, i = 0; i < len; i++) { if (*cp == '\\') { cp++; @@ -3497,7 +3231,7 @@ bad_quote: } cp++; } else { - strncpy(valptr, cp = dp, len); + strncpy(valptr, cp = dp, len); cp += len; } @@ -3570,9 +3304,9 @@ bad_quote: */ if (index == 0 && encoded) { - mh_xfree(pp->charset); - pp->charset = charset; - mh_xfree(pp->lang); + free(pp->charset); + pp->charset = charset; + free(pp->lang); pp->lang = lang; } } else { @@ -3595,7 +3329,7 @@ bad_quote: */ for (pp = phead; pp != NULL; ) { - char *p, *q; + char *p, *q; size_t tlen = 0; int pindex = 0; for (sp = pp->sechead; sp != NULL; sp = sp->next) { @@ -3637,7 +3371,8 @@ bad_quote: */ char * -content_charset (CT ct) { +content_charset (CT ct) +{ char *ret_charset = NULL; ret_charset = get_param(ct->c_ctinfo.ci_first_pm, "charset", '?', 0); @@ -3671,7 +3406,7 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external) if (strlen(params->pm_name) > CPERLIN) { inform("Parameter name \"%s\" is too long", params->pm_name); - mh_xfree(paramout); + free(paramout); return NULL; } @@ -3708,7 +3443,7 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external) numchars, valoff); if (i == 0) { - mh_xfree(paramout); + free(paramout); return NULL; } @@ -3757,7 +3492,7 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external) if (index > 0) { q += snprintf(q, sizeof(line) - (q - line), "%s*%d", - params->pm_name, index); + params->pm_name, index); } else { strncpy(q, params->pm_name, sizeof(line) - (q - line)); q += strlen(q); @@ -3765,13 +3500,13 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external) if (encode) i = encode_param(params, q, sizeof(line) - (q - line), - strlen(params->pm_value + valoff), valoff, index); + strlen(params->pm_value + valoff), valoff, index); else i = normal_param(params, q, sizeof(line) - (q - line), - strlen(params->pm_value + valoff), valoff); + strlen(params->pm_value + valoff), valoff); if (i == 0) { - mh_xfree(paramout); + free(paramout); return NULL; } @@ -3872,7 +3607,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont, if (! pm->pm_charset) { pm->pm_charset = mh_xstrdup(write_charset_8bit()); if (strcasecmp(pm->pm_charset, "US-ASCII") == 0) - adios(NULL, "8-bit characters in parameter \"%s\", but " + die("8-bit characters in parameter \"%s\", but " "local character set is US-ASCII", pm->pm_name); } if (! pm->pm_lang) @@ -3896,7 +3631,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont, len += 3; maxfit -= 3; } else { - len++; + len++; maxfit--; } /* @@ -3909,7 +3644,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont, fitlimit++; } } else { - /* + /* * Calculate the string length, but add room for quoting \ * and " if necessary. Also account for quotes at beginning * and end. @@ -3918,7 +3653,7 @@ param_len(PM pm, int index, size_t valueoff, int *encode, int *cont, switch (*p) { case '"': case '\\': - len++; + len++; maxfit--; /* FALLTHRU */ default: @@ -4067,7 +3802,7 @@ add_param(PM *first, PM *last, char *name, char *value, int nocopy) (*last)->pm_next = pm; *last = pm; } else { - *first = pm; + *first = pm; *last = pm; } @@ -4112,7 +3847,7 @@ get_param(PM first, const char *name, char replace, int fetchonly) while (first != NULL) { if (strcasecmp(name, first->pm_name) == 0) { if (fetchonly) - return first->pm_value; + return first->pm_value; return getcpy(get_param_value(first, replace)); } first = first->pm_next; @@ -4126,7 +3861,8 @@ get_param(PM first, const char *name, char replace, int fetchonly) * necessary */ -char *get_param_value(PM pm, char replace) +char * +get_param_value(PM pm, char replace) { static char buffer[4096]; /* I hope no parameters are larger */ size_t bufsize = sizeof(buffer); @@ -4148,7 +3884,7 @@ char *get_param_value(PM pm, char replace) */ if (!pm->pm_charset || check_charset(pm->pm_charset, - strlen(pm->pm_charset))) { + strlen(pm->pm_charset))) { return pm->pm_value; }