*/
char *tmp;
+/*
+ * These are for mhfixmsg to:
+ * 1) Instruct parser not to detect invalid Content-Transfer-Encoding
+ * in a multipart.
+ * 2) Suppress the warning about bogus multipart content, and report it.
+ */
+int skip_mp_cte_check;
+int suppress_bogus_mp_content_warning;
+int bogus_mp_content;
+
/*
* Structures for TEXT messages
*/
void content_error (char *, CT, char *, ...);
/* mhfree.c */
-void free_content (CT);
void free_encoding (CT, int);
/*
static int InitMail (CT);
static int openMail (CT, char **);
static int readDigest (CT, char *);
+static int get_leftover_mp_content (CT, int);
struct str2init str2cts[] = {
{ "application", CT_APPLICATION, InitApplication },
* The encoding for multipart messages must be either
* 7bit, 8bit, or binary (per RFC2045).
*/
- if (ct->c_encoding != CE_7BIT && ct->c_encoding != CE_8BIT
- && ct->c_encoding != CE_BINARY) {
+ if (! skip_mp_cte_check && ct->c_encoding != CE_7BIT &&
+ ct->c_encoding != CE_8BIT && ct->c_encoding != CE_BINARY) {
/* Copy the Content-Transfer-Encoding header field body so we can
remove any trailing whitespace and leading blanks from it. */
char *cte = add (ct->c_celine ? ct->c_celine : "(null)", NULL);
}
}
- advise (NULL, "bogus multipart content in message %s", ct->c_file);
+ if (! suppress_bogus_mp_content_warning) {
+ advise (NULL, "bogus multipart content in message %s", ct->c_file);
+ }
+ bogus_mp_content = 1;
+
if (!inout && part) {
p = part->mp_part;
p->c_end = ct->c_end;
}
}
+ get_leftover_mp_content (ct, 1);
+ get_leftover_mp_content (ct, 0);
+
fclose (ct->c_fp);
ct->c_fp = NULL;
return OK;
return OK;
}
+
+
+/* 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. */
+int
+get_leftover_mp_content (CT ct, int before /* or after */) {
+ struct multipart *m = (struct multipart *) ct->c_ctparams;
+ char *boundary;
+ int found_boundary = 0;
+ char buffer[BUFSIZ];
+ int max = BUFSIZ;
+ int read = 0;
+ char *content = NULL;
+
+ if (! m) return NOTOK;
+
+ if (before) {
+ if (! m->mp_parts || ! m->mp_parts->mp_part) return NOTOK;
+
+ /* Isolate the beginning of this part to the beginning of the
+ first subpart and save any content between them. */
+ fseeko (ct->c_fp, ct->c_begin, SEEK_SET);
+ max = m->mp_parts->mp_part->c_begin - ct->c_begin;
+ boundary = concat ("--", m->mp_start, NULL);
+ } else {
+ struct part *last_subpart = NULL;
+ struct part *subpart;
+
+ /* Go to the last subpart to get its end position. */
+ for (subpart = m->mp_parts; subpart; subpart = subpart->mp_next) {
+ last_subpart = subpart;
+ }
+
+ if (last_subpart == NULL) return NOTOK;
+
+ /* Isolate the end of the last subpart to the end of this part
+ and save any content between them. */
+ fseeko (ct->c_fp, last_subpart->mp_part->c_end, SEEK_SET);
+ max = ct->c_end - last_subpart->mp_part->c_end;
+ boundary = concat ("--", m->mp_stop, NULL);
+ }
+
+ /* Back up by 1 to pick up the newline. */
+ while (fgets (buffer, sizeof(buffer) - 1, ct->c_fp)) {
+ read += strlen (buffer);
+ /* Don't look beyond beginning of first subpart (before) or
+ next part (after). */
+ if (read > max) buffer[read-max] = '\0';
+
+ if (before) {
+ if (! strcmp (buffer, boundary)) {
+ found_boundary = 1;
+ }
+ } else {
+ if (! found_boundary && ! strcmp (buffer, boundary)) {
+ found_boundary = 1;
+ continue;
+ }
+ }
+
+ if ((before && ! found_boundary) || (! before && found_boundary)) {
+ if (content) {
+ char *old_content = content;
+ content = concat (content, buffer, NULL);
+ free (old_content);
+ } else {
+ content = before
+ ? concat ("\n", buffer, NULL)
+ : concat (buffer, NULL);
+ }
+ }
+
+ if (before) {
+ if (found_boundary || read > max) break;
+ } else {
+ if (read > max) break;
+ }
+ }
+
+ /* Skip the newline if that's all there is. */
+ if (content) {
+ char *cp;
+
+ /* Remove trailing newline, except at EOF. */
+ if ((before || ! feof (ct->c_fp)) &&
+ (cp = content + strlen (content)) > content &&
+ *--cp == '\n') {
+ *cp = '\0';
+ }
+
+ if (strlen (content) > 1) {
+ if (before) {
+ m->mp_content_before = content;
+ } else {
+ m->mp_content_after = content;
+ }
+ } else {
+ free (content);
+ }
+ }
+
+ free (boundary);
+
+ return OK;
+}