* 1) Instruct parser not to detect invalid Content-Transfer-Encoding
* in a multipart.
* 2) Suppress the warning about bogus multipart content, and report it.
+ * 3) Suppress the warning about extraneous trailing ';' in header parameter
+ * lists, and report it.
*/
int skip_mp_cte_check;
int suppress_bogus_mp_content_warning;
int bogus_mp_content;
+int suppress_extraneous_trailing_semicolon_warning;
+int extraneous_trailing_semicolon;
/*
* Structures for TEXT messages
{ "alternative", MULTI_ALTERNATE },
{ "digest", MULTI_DIGEST },
{ "parallel", MULTI_PARALLEL },
+ { "related", MULTI_RELATED },
{ NULL, MULTI_UNKNOWN } /* this one must be last! */
};
static int InitGeneric (CT);
static int InitText (CT);
static int InitMultiPart (CT);
-void reverse_parts (CT);
+static void reverse_parts (CT);
static int InitMessage (CT);
static int InitApplication (CT);
static int init_encoding (CT, OpenCEFunc);
m_getfld_state_t gstate = 0;
/* allocate the content structure */
- if (!(ct = (CT) calloc (1, sizeof(*ct))))
+ if (!(ct = (CT) mh_xcalloc (1, sizeof(*ct))))
adios (NULL, "out of memory");
ct->c_fp = in;
ct->c_subtype = kv->kv_value;
/* allocate text character set structure */
- if ((t = (struct text *) calloc (1, sizeof(*t))) == NULL)
+ if ((t = (struct text *) mh_xcalloc (1, sizeof(*t))) == NULL)
adios (NULL, "out of memory");
ct->c_ctparams = (void *) t;
}
/* allocate primary structure for multipart info */
- if ((m = (struct multipart *) calloc (1, sizeof(*m))) == NULL)
+ if ((m = (struct multipart *) mh_xcalloc (1, sizeof(*m))) == NULL)
adios (NULL, "out of memory");
ct->c_ctparams = (void *) m;
if (strcmp (bufp + 2, m->mp_start))
continue;
next_part:
- if ((part = (struct part *) calloc (1, sizeof(*part))) == NULL)
+ if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
adios (NULL, "out of memory");
*next = part;
next = &part->mp_next;
if (!(p = get_content (fp, ct->c_file,
ct->c_subtype == MULTI_DIGEST ? -1 : 0))) {
free(bufp);
- fclose (ct->c_fp);
ct->c_fp = NULL;
return NOTOK;
}
* reverse the order of the parts of a multipart/alternative
*/
-void
+static void
reverse_parts (CT ct)
{
struct multipart *m = (struct multipart *) ct->c_ctparams;
}
+
+
+/* parse_mime() arranges alternates in reverse (priority) order. This
+ function can be used to reverse them back. This will put, for
+ 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) {
+ if (ct->c_type == CT_MULTIPART) {
+ struct multipart *m = (struct multipart *) ct->c_ctparams;
+ struct part *part;
+
+ if (ct->c_subtype == MULTI_ALTERNATE) {
+ reverse_parts (ct);
+ }
+
+ /* And call recursively on each part of a multipart. */
+ for (part = m->mp_parts; part; part = part->mp_next) {
+ reverse_alternative_parts (part->mp_part);
+ }
+ }
+}
+
+
/*
* MESSAGE
*/
PM pm;
struct partial *p;
- if ((p = (struct partial *) calloc (1, sizeof(*p))) == NULL)
+ if ((p = (struct partial *) mh_xcalloc (1, sizeof(*p))) == NULL)
adios (NULL, "out of memory");
ct->c_ctparams = (void *) p;
CT p;
FILE *fp;
- if ((e = (struct exbody *) calloc (1, sizeof(*e))) == NULL)
+ if ((e = (struct exbody *) mh_xcalloc (1, sizeof(*e))) == NULL)
adios (NULL, "out of memory");
ct->c_ctparams = (void *) e;
/* sbeck@cise.ufl.edu -- handle suffixes */
ci = &ct->c_ctinfo;
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s",
- invo_name, ci->ci_type, ci->ci_subtype);
- cp = context_find (buffer);
- if (cp == NULL || *cp == '\0') {
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name,
- ci->ci_type);
- cp = context_find (buffer);
- }
- if (cp != NULL && *cp != '\0') {
+ if ((cp = context_find_by_type ("suffix", ci->ci_type, ci->ci_subtype))) {
if (ce->ce_unlink) {
/* Create temporary file with filename extension. */
if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) {
{
int cc, digested, len, quoted, own_ct_fp = 0;
char *cp, *ep;
- char buffer[BUFSIZ];
char *bufp = NULL;
size_t buflen;
ssize_t gotlen;
/* sbeck@cise.ufl.edu -- handle suffixes */
ci = &ct->c_ctinfo;
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s",
- invo_name, ci->ci_type, ci->ci_subtype);
- cp = context_find (buffer);
- if (cp == NULL || *cp == '\0') {
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name,
- ci->ci_type);
- cp = context_find (buffer);
- }
- if (cp != NULL && *cp != '\0') {
+ if ((cp = context_find_by_type ("suffix", ci->ci_type, ci->ci_subtype))) {
if (ce->ce_unlink) {
/* Create temporary file with filename extension. */
if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) {
fclose (ct->c_fp);
ct->c_fp = NULL;
}
+ free (bufp);
return fileno (ce->ce_fp);
clean_up:
fclose (ct->c_fp);
ct->c_fp = NULL;
}
+ free (bufp);
return NOTOK;
}
/* sbeck@cise.ufl.edu -- handle suffixes */
ci = &ct->c_ctinfo;
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s/%s",
- invo_name, ci->ci_type, ci->ci_subtype);
- cp = context_find (buffer);
- if (cp == NULL || *cp == '\0') {
- snprintf (buffer, sizeof(buffer), "%s-suffix-%s", invo_name,
- ci->ci_type);
- cp = context_find (buffer);
- }
- if (cp != NULL && *cp != '\0') {
+ if ((cp = context_find_by_type ("suffix", ci->ci_type, ci->ci_subtype))) {
if (ce->ce_unlink) {
/* Create temporary file with filename extension. */
if ((ce->ce_file = m_mktemps(invo_name, cp, NULL, NULL)) == NULL) {
cc = len;
len -= cc;
- fwrite (buffer, sizeof(*buffer), cc, ce->ce_fp);
+ if ((int) fwrite (buffer, sizeof(*buffer), cc, ce->ce_fp) < cc) {
+ advise ("open7Bit", "fwrite");
+ }
if (ferror (ce->ce_fp)) {
content_error (ce->ce_file, ct, "error writing to");
goto clean_up;
}
}
+ *fd = fileno (ce->ce_fp);
return OK;
ready_already:
while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
> 0)
- fwrite (buffer, sizeof(*buffer), cc, fp);
+ if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+ advise ("openFile", "fwrite");
+ }
fflush (fp);
if (ferror (gp)) {
while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
> 0)
- fwrite (buffer, sizeof(*buffer), cc, fp);
+ if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+ advise ("openFTP", "fwrite");
+ }
fflush (fp);
if (ferror (gp)) {
while ((cc = fread(buffer, sizeof(*buffer),
sizeof(buffer), gp)) > 0)
- fwrite(buffer, sizeof(*buffer), cc, fp);
+ if ((int) fwrite(buffer, sizeof(*buffer), cc, fp) < cc) {
+ advise ("openURL", "fwrite");
+ }
fflush(fp);
return "digest";
case MULTI_PARALLEL:
return "parallel";
+ case MULTI_RELATED:
+ return "related";
default:
return "unknown_multipart_subtype";
}
}
if (*cp == 0) {
- advise (NULL,
- "extraneous trailing ';' in message %s's %s: "
- "parameter list",
- filename, fieldname);
+ if (! suppress_extraneous_trailing_semicolon_warning) {
+ advise (NULL,
+ "extraneous trailing ';' in message %s's %s: "
+ "parameter list",
+ filename, fieldname);
+ }
+ extraneous_trailing_semicolon = 1;
return DONE;
}
"%s's %s: field\n%*s(parameter %s)", sp->index,
filename, fieldname, strlen(invo_name) + 2, "",
nameptr);
+ free (nameptr);
return NOTOK;
}
if (sp2->index < sp->index &&
"param in message %s's %s: field\n%*s(parameter %s)",
filename, fieldname, strlen(invo_name) + 2, "",
nameptr);
+ free (nameptr);
return NOTOK;
}
}
}
/*
- * Return the charset for a particular content type. Return pointer is
- * only valid until the next call to content_charset().
+ * Return the charset for a particular content type.
*/
char *
content_charset (CT ct) {
- static char *ret_charset = NULL;
-
- if (ret_charset != NULL) {
- free(ret_charset);
- }
+ char *ret_charset = NULL;
ret_charset = get_param(ct->c_ctinfo.ci_first_pm, "charset", '?', 0);
- return ret_charset ? ret_charset : "US-ASCII";
+ return ret_charset ? ret_charset : getcpy ("US-ASCII");
}
* add them now.
*/
- if (! pm->pm_charset)
+ if (! pm->pm_charset) {
pm->pm_charset = getcpy(write_charset_8bit());
+ if (strcasecmp(pm->pm_charset, "US-ASCII") == 0)
+ adios(NULL, "8-bit characters in parameter \"%s\", but "
+ "local character set is US-ASCII", pm->pm_name);
+ }
if (! pm->pm_lang)
pm->pm_lang = getcpy(NULL); /* Default to a blank lang tag */