#include <h/mh.h>
#include <fcntl.h>
-#include <h/signals.h>
#include <h/md5.h>
#include <h/mts.h>
#include <h/tws.h>
static void set_charset (CT, int);
static void expand_pseudoheaders (CT, struct multipart *, const char *,
const convert_list *);
-static void expand_pseudoheader (CT, struct multipart *, const char *,
+static void expand_pseudoheader (CT, CT *, struct multipart *, const char *,
const char *, const char *);
static char *fgetstr (char *, int, FILE *);
static int user_content (FILE *, char *, CT *, const char *infilename);
void
expand_pseudoheaders (CT ct, struct multipart *m, const char *infile,
const convert_list *convert_head) {
+ /* text_plain_ct is used to concatenate all of the text/plain
+ replies into one part, instead of having each one in a separate
+ part. */
+ CT text_plain_ct = NULL;
+
switch (ct->c_type) {
case CT_MULTIPART: {
struct multipart *mp = (struct multipart *) ct->c_ctparams;
part->mp_part->c_ctinfo.ci_subtype, NULL);
if (part->mp_part->c_type == CT_MULTIPART) {
- expand_pseudoheaders (part->mp_part, mp, infile,
+ expand_pseudoheaders (part->mp_part, m, infile,
convert_head);
} else {
const convert_list *c;
for (c = convert_head; c; c = c->next) {
if (! strcasecmp (type_subtype, c->type)) {
- expand_pseudoheader (part->mp_part, m, infile,
+ expand_pseudoheader (part->mp_part, &text_plain_ct,
+ m, infile,
c->type, c->argstring);
matched = 1;
break;
for (c = convert_head; c; c = c->next) {
if (! strcasecmp (type_subtype, c->type)) {
- expand_pseudoheader (ct, m, infile, c->type, c->argstring);
+ expand_pseudoheader (ct, &text_plain_ct, m, infile, c->type,
+ c->argstring);
break;
}
}
* Expand a single pseudoheader. It's for the specified type.
*/
void
-expand_pseudoheader (CT ct, struct multipart *m, const char *infile,
- const char *type, const char *argstring) {
- /* text_plain_ct is used to concatenate all of the text/plain
- replies into one part, instead of having each one in a separate
- part. */
- CT text_plain_ct = NULL;
+expand_pseudoheader (CT ct, CT *text_plain_ct, struct multipart *m,
+ const char *infile, const char *type,
+ const char *argstring) {
char *reply_file;
FILE *reply_fp = NULL;
char *convert, *type_p, *subtype_p;
struct str2init *s2i;
CT reply_ct;
struct part *part;
+ int status;
type_p = getcpy (type);
if ((subtype_p = strchr (type_p, '/'))) {
/* Convert here . . . */
ct->c_storeproc = getcpy (convert_command);
ct->c_umask = ~m_gmprot ();
- if (show_content_aux (ct, 0, convert_command, NULL, NULL) == NOTOK) {
+
+ if ((status = show_content_aux (ct, 0, convert_command, NULL, NULL)) !=
+ OK) {
admonish (NULL, "store of %s content failed", type);
}
free (convert_command);
} else {
set_charset (reply_ct, -1);
charset = get_param (reply_ct->c_ctinfo.ci_first_pm, "charset", '?', 1);
- if (reply_ct->c_reqencoding == CE_UNKNOWN &&
- strcasecmp (charset, "US-ASCII")) {
+ if (reply_ct->c_reqencoding == CE_UNKNOWN) {
/* Assume that 8bit is sufficient (for text). */
- reply_ct->c_reqencoding = CE_8BIT;
+ reply_ct->c_reqencoding =
+ strcasecmp (charset, "US-ASCII") ? CE_8BIT : CE_7BIT;
}
}
/* Concatenate text/plain parts. */
if (reply_ct->c_type == CT_TEXT &&
reply_ct->c_subtype == TEXT_PLAIN) {
-
- if (m->mp_parts && ! text_plain_ct) {
- text_plain_ct = m->mp_parts->mp_part;
+ if (! *text_plain_ct && m->mp_parts && m->mp_parts->mp_part &&
+ m->mp_parts->mp_part->c_type == CT_TEXT &&
+ m->mp_parts->mp_part->c_subtype == TEXT_PLAIN) {
+ *text_plain_ct = m->mp_parts->mp_part;
/* Make sure that the charset is set in the text/plain
part. */
- set_charset (text_plain_ct, -1);
- if (text_plain_ct->c_reqencoding == CE_UNKNOWN &&
- strcasecmp (charset, "US-ASCII")) {
+ set_charset (*text_plain_ct, -1);
+ if ((*text_plain_ct)->c_reqencoding == CE_UNKNOWN) {
/* Assume that 8bit is sufficient (for text). */
- text_plain_ct->c_reqencoding = CE_8BIT;
+ (*text_plain_ct)->c_reqencoding =
+ strcasecmp (charset, "US-ASCII") ? CE_8BIT : CE_7BIT;
}
}
- if (text_plain_ct) {
+ if (*text_plain_ct) {
/* Only concatenate if the charsets are identical. */
char *text_plain_ct_charset =
- get_param (text_plain_ct->c_ctinfo.ci_first_pm, "charset",
+ get_param ((*text_plain_ct)->c_ctinfo.ci_first_pm, "charset",
'?', 1);
if (strcasecmp (text_plain_ct_charset, charset) == 0) {
If there's a problem anywhere along the way,
instead attach it is a separate part. */
int text_plain_reply =
- open (text_plain_ct->c_cefile.ce_file,
+ open ((*text_plain_ct)->c_cefile.ce_file,
O_WRONLY | O_APPEND);
int addl_reply = open (reply_file, O_RDONLY);
if (text_plain_reply != NOTOK && addl_reply != NOTOK) {
/* Insert blank line before each addl part. */
+ /* It would be nice not to do this for the first one. */
if (write (text_plain_reply, "\n", 1) == 1) {
/* Copy the text from the new reply and
then free its Content struct. */
cpydata (addl_reply, text_plain_reply,
- text_plain_ct->c_cefile.ce_file,
+ (*text_plain_ct)->c_cefile.ce_file,
reply_file);
if (close (text_plain_reply) == OK &&
close (addl_reply) == OK) {
}
}
} else {
- text_plain_ct = reply_ct;
+ *text_plain_ct = reply_ct;
}
}
buffer[statbuf.st_size] = '\0';
/* Look for a header in the convert reply. */
- if ((end_of_header = strstr (buffer, "\r\n\r\n"))) {
- end_of_header += 2;
- found_header = 1;
- } else if ((end_of_header = strstr (buffer, "\n\n"))) {
- ++end_of_header;
- found_header = 1;
+ if (strncasecmp (buffer, TYPE_FIELD, strlen (TYPE_FIELD)) == 0 &&
+ buffer[strlen (TYPE_FIELD)] == ':') {
+ if ((end_of_header = strstr (buffer, "\r\n\r\n"))) {
+ end_of_header += 2;
+ found_header = 1;
+ } else if ((end_of_header = strstr (buffer, "\n\n"))) {
+ ++end_of_header;
+ found_header = 1;
+ }
}
if (found_header) {