/* mhfree.c */
extern CT *cts;
-void freects_done (int) NORETURN;
/*
* static prototypes
char *textcharset;
} fix_transformations;
-int mhfixmsgsbr (CT *, const fix_transformations *, char *);
+int mhfixmsgsbr (CT *, char *, const fix_transformations *, char *);
static int fix_boundary (CT *, int *);
static int copy_input_to_output (const char *, const char *);
static int get_multipart_boundary (CT, char **);
main (int argc, char **argv) {
int msgnum;
char *cp, *file = NULL, *folder = NULL;
- char *maildir, buf[100], *outfile = NULL;
+ char *maildir = NULL, buf[100], *outfile = NULL;
char **argp, **arguments;
struct msgs_array msgs = { 0, 0, NULL };
struct msgs *mp = NULL;
fx.lf_line_endings = 0;
fx.textcharset = NULL;
- if (nmh_init(argv[0], 1)) { return 1; }
-
- done = freects_done;
+ if (nmh_init(argv[0], 2)) { return 1; }
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
}
}
- if (! (cts = (CT *) mh_xcalloc ((size_t) 2, sizeof *cts))) {
- adios (NULL, "out of memory");
- }
+ cts = mh_xcalloc(2, sizeof *cts);
ctp = cts;
if ((ct = parse_mime (file))) {
}
maildir = m_maildir (folder);
+ /* chdir so that error messages, esp. from MIME parser, just
+ refer to the message and not its path. */
if (chdir (maildir) == NOTOK) {
adios (maildir, "unable to change directory to");
}
}
seq_setprev (mp); /* set the previous-sequence */
- if (! (cts =
- (CT *) mh_xcalloc ((size_t) (mp->numsel + 1), sizeof *cts))) {
- adios (NULL, "out of memory");
- }
+ cts = mh_xcalloc(mp->numsel + 1, sizeof *cts);
ctp = cts;
for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
if (is_selected(mp, msgnum)) {
- char *msgnam;
+ char *msgnam = m_name (msgnum);
- msgnam = m_name (msgnum);
if ((ct = parse_mime (msgnam))) {
set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings);
*ctp++ = ct;
advise (NULL, "unable to parse message %s", msgnam);
status = NOTOK;
- /* If there's an outfile, pass the input message unchanged, so the message won't
- get dropped from a pipeline. */
+ /* If there's an outfile, pass the input message
+ unchanged, so the message won't get dropped from a
+ pipeline. */
if (outfile) {
- /* Something went wrong. Output might be expected, such as if this were run
- as a filter. Just copy the input to the output. */
- const char *input_filename = path (msgnam, TFILE);
+ /* Something went wrong. Output might be expected,
+ such as if this were run as a filter. Just copy
+ the input to the output. */
+ /* Can't use path() here because 1) it might have been
+ called before and it caches the pwd, and 2) we call
+ chdir() after that. */
+ char *input_filename =
+ concat (maildir, "/", msgnam, NULL);
if (copy_input_to_output (input_filename, outfile) != OK) {
- advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
+ advise (NULL,
+ "unable to copy message to %s, it might be lost\n",
+ outfile);
}
+ free (input_filename);
}
}
}
if (*cts) {
for (ctp = cts; *ctp; ++ctp) {
- status += mhfixmsgsbr (ctp, &fx, outfile);
+ status += mhfixmsgsbr (ctp, maildir, &fx, outfile);
+ free_content (*ctp);
if (using_stdin) {
(void) m_unlink (file);
}
}
}
+
+ free (cts);
} else {
status = 1;
}
free (folder);
free (arguments);
- /* done is freects_done, which will clean up all of cts. */
done (status);
return NOTOK;
}
* Apply transformations to one message.
*/
int
-mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) {
+mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx,
+ char *outfile) {
/* Store input filename in case one of the transformations, i.e.,
fix_boundary(), rewrites to a tmp file. */
- char *input_filename = add ((*ctp)->c_file, NULL);
+ char *input_filename = maildir
+ ? concat (maildir, "/", (*ctp)->c_file, NULL)
+ : add ((*ctp)->c_file, NULL);
int modify_inplace = 0;
int message_mods = 0;
int status = OK;
*/
static int
get_multipart_boundary (CT ct, char **part_boundary) {
- char buffer[BUFSIZ];
+ char buffer[NMH_BUFSIZ];
char *end_boundary = NULL;
off_t begin = (off_t) ct->c_end > (off_t) (ct->c_begin + sizeof buffer)
? (off_t) (ct->c_end - sizeof buffer)
size_t bytes_read;
int status = OK;
- /* This will fail if the boundary spans fread() calls. BUFSIZ should
+ /* This will fail if the boundary spans fread() calls. NMH_BUFSIZ should
be big enough, even if it's just 1024, to make that unlikely. */
- /* free_content() will close ct->c_fp. */
+ /* free_content() will close ct->c_fp if bogus MP boundary is fixed. */
if (! ct->c_fp && (ct->c_fp = fopen (ct->c_file, "r")) == NULL) {
advise (ct->c_file, "unable to open for reading");
return NOTOK;
status = NOTOK;
}
+ if (ct->c_fp) {
+ fclose (ct->c_fp);
+ ct->c_fp = NULL;
+ }
+
if (status == OK) {
*part_boundary = end_boundary;
} else {
replace_boundary (CT ct, char *file, char *boundary) {
FILE *fpin, *fpout;
int compnum, state;
- char buf[BUFSIZ], name[NAMESZ];
+ char buf[NMH_BUFSIZ], name[NAMESZ];
char *np, *vp;
m_getfld_state_t gstate = 0;
int status = OK;
fprintf (fpout, "%s:%s%s\n", np, new_ctline,
new_params ? new_params : "");
free(new_ctline);
- if (new_params) {
- free(new_params);
- }
+ mh_xfree(new_params);
}
free (vp);
continue;
case BODY:
- fputs ("\n", fpout);
+ putc('\n', fpout);
/* buf will have a terminating NULL, skip it. */
if ((int) fwrite (buf, 1, bufsz-1, fpout) < bufsz-1) {
advise (file, "fwrite");
* c_ctline
*/
/* Extract type and subtype from type/subtype. */
- ct_type = getcpy (ct_type_subtype);
+ ct_type = mh_xstrdup(ct_type_subtype);
if ((cp = strchr (ct_type, '/'))) {
*cp = '\0';
- ct_subtype = getcpy (++cp);
+ ct_subtype = mh_xstrdup(++cp);
} else {
advise (NULL, "missing / in MIME type of %s %s",
ct->c_file, ct->c_partno);
char *prefix, *new_str;
if (cp - *str) {
- prefix = getcpy (*str);
+ prefix = mh_xstrdup(*str);
*(prefix + (cp - *str)) = '\0';
new_str = concat (prefix, new, remainder, NULL);
free (prefix);
free (*str);
return *str = new_str;
- } else {
- return NULL;
}
+
+ return NULL;
}
if (! strncasecmp (name, ENCODING_FIELD,
strlen (ENCODING_FIELD))) {
char *prefix = "Nmh-REPLACED-INVALID-";
- HF h = mh_xmalloc (sizeof *h);
+ HF h;
+ NEW(h);
h->name = add (hf->name, NULL);
h->hf_encoding = hf->hf_encoding;
h->next = hf->next;
ct->c_cefile.ce_file to the name of the file containing
the contents. */
+ if (ct->c_ceclosefnx) {
+ (*ct->c_ceclosefnx) (ct);
+ }
+
/* Restore the cefile. */
ct->c_cefile = decoded_content_info;
ct->c_celine = add (cte, NULL);
return OK;
- } else {
- return NOTOK;
}
+
+ return NOTOK;
}
HF hf;
parent->c_subtype = MULTI_ALTERNATE;
- parent->c_ctinfo.ci_subtype = getcpy ("alternative");
+ parent->c_ctinfo.ci_subtype = mh_xstrdup("alternative");
if (! replace_substring (&parent->c_ctline, "/related",
"/alternative")) {
advise (NULL,
static int
insert_new_text_plain_part (CT ct, int new_subpart_number, CT parent) {
struct multipart *mp = (struct multipart *) parent->c_ctparams;
- struct part *new_part = mh_xmalloc (sizeof *new_part);
+ struct part *new_part;
+ NEW(new_part);
if ((new_part->mp_part = build_text_plain_part (ct))) {
char buffer[16];
snprintf (buffer, sizeof buffer, "%d", new_subpart_number);
buffer, NULL);
return 1;
- } else {
- free_content (new_part->mp_part);
- free (new_part);
-
- return 0;
}
+
+ free_content (new_part->mp_part);
+ free (new_part);
+
+ return 0;
}
divide_part (CT ct) {
CT new_part;
- if ((new_part = (CT) mh_xcalloc (1, sizeof *new_part)) == NULL)
- adios (NULL, "out of memory");
-
+ NEW0(new_part);
/* Just copy over what is needed for decoding. c_vrsn and
c_celine aren't necessary. */
new_part->c_file = add (ct->c_file, NULL);
d_pm = add_param(&dest->ci_first_pm, &dest->ci_last_pm, s_pm->pm_name,
s_pm->pm_value, 0);
if (s_pm->pm_charset) {
- d_pm->pm_charset = getcpy(s_pm->pm_charset);
+ d_pm->pm_charset = mh_xstrdup(s_pm->pm_charset);
}
if (s_pm->pm_lang) {
- d_pm->pm_lang = getcpy(s_pm->pm_lang);
+ d_pm->pm_lang = mh_xstrdup(s_pm->pm_lang);
}
}
ct->c_file, invo_name, type, subtype);
}
return NOTOK;
- } else {
- if (strchr (cf, '>')) {
- advise (NULL, "'>' prohibited in \"%s\",\nplease fix your "
- "%s-format-%s/%s profile entry", cf, invo_name, type,
- subtype ? subtype : "");
+ }
+ if (strchr (cf, '>')) {
+ advise (NULL, "'>' prohibited in \"%s\",\nplease fix your "
+ "%s-format-%s/%s profile entry", cf, invo_name, type,
+ subtype ? subtype : "");
- return NOTOK;
- }
+ return NOTOK;
}
cp = concat (cf, " >", file, NULL);
}
output_encoding = content_encoding (ct, &reason);
- if (set_ct_type (ct, c_type, output_subtype, output_encoding) == OK) {
+ if (status == OK &&
+ set_ct_type (ct, c_type, output_subtype, output_encoding) == OK) {
ct->c_cefile.ce_file = file;
ct->c_cefile.ce_unlink = 1;
} else {
struct multipart *m;
const struct str2init *ctinit;
- if ((ct = (CT) mh_xcalloc (1, sizeof *ct)) == NULL)
- adios (NULL, "out of memory");
+ NEW0(ct);
/* Set up the multipart/alternative part. These fields of *ct were
initialized to 0 by mh_xcalloc():
add_param(&ct->c_ctinfo.ci_first_pm, &ct->c_ctinfo.ci_last_pm,
"boundary", boundary, 0);
- p = (struct part *) mh_xmalloc (sizeof *p);
- p->mp_next = (struct part *) mh_xmalloc (sizeof *p->mp_next);
+ NEW(p);
+ NEW(p->mp_next);
p->mp_next->mp_next = NULL;
p->mp_next->mp_part = first_alt;
- if ((m = (struct multipart *) mh_xcalloc (1, sizeof (struct multipart))) ==
- NULL)
- adios (NULL, "out of memory");
+ NEW0(m);
m->mp_start = concat (boundary, "\n", NULL);
m->mp_stop = concat (boundary, "--\n", NULL);
m->mp_parts = p;
*/
static int
boundary_in_content (FILE **fp, char *file, const char *boundary) {
- char buffer[BUFSIZ];
+ char buffer[NMH_BUFSIZ];
size_t bytes_read;
int found_boundary = 0;
if (ce->ce_file) {
size_t line_len = 0;
- char buffer[BUFSIZ];
+ char buffer[NMH_BUFSIZ];
size_t inbytes;
if (! ce->ce_fp && (ce->ce_fp = fopen (ce->ce_file, "r")) == NULL) {
}
if (fp && *fp) {
- char buffer[BUFSIZ];
+ char buffer[NMH_BUFSIZ];
size_t bytes_read;
size_t bytes_to_read =
end > 0 && end > begin ? end - begin : sizeof buffer;
status = NOTOK;
} else {
/* Replace the decoded file with the converted one. */
- if (ct->c_cefile.ce_file) {
- if (ct->c_cefile.ce_unlink) {
- (void) m_unlink (ct->c_cefile.ce_file);
- }
- free (ct->c_cefile.ce_file);
- }
+ if (ct->c_cefile.ce_file && ct->c_cefile.ce_unlink)
+ (void) m_unlink (ct->c_cefile.ce_file);
+
+ mh_xfree(ct->c_cefile.ce_file);
ct->c_cefile.ce_file = stripped_content_file;
ct->c_cefile.ce_unlink = 1;
*/
static int
fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) {
- size_t value_len;
int fixed = 0;
- if (((value_len = strlen (value)) > 0) &&
- strncmp (value, "=?", 2) == 0 &&
- strncmp (&value[value_len - 2], "?=", 2) == 0) {
+ if (HasPrefix(value, "=?") && HasSuffix(value, "?=")) {
/* Looks like an RFC 2047 encoded parameter. */
char decoded[PATH_MAX + 1];
const char *const new_params = concat (params, "\n", NULL);
replace_substring (&hf->value, semicolon_loc, new_params);
- free ((char *) new_params);
- free ((char *) params);
+ free((void *)new_params); /* Cast away const. Sigh. */
+ free((void *)params);
} else {
advise (NULL, "did not find semicolon in %s:%s\n",
hf->name, hf->value);
int i = -1;
if (old != -1 && new != -1) {
- char buffer[BUFSIZ];
+ char buffer[NMH_BUFSIZ];
while ((i = read (old, buffer, sizeof buffer)) >
0) {
default:
if (should_decode(decodetypes, ct->c_ctinfo.ci_type, ct->c_ctinfo.ci_subtype)) {
if (ct->c_ctparams == NULL) {
- if ((ct->c_ctparams = (struct text *) mh_xcalloc (1, sizeof (struct text))) == NULL) {
- adios (NULL, "out of memory");
- }
+ ct->c_ctparams = mh_xcalloc(1, sizeof (struct text));
}
((struct text *) ct->c_ctparams)->lf_line_endings = lf_line_endings;
}
free (rmm_command);
return WIFEXITED (status) ? WEXITSTATUS (status) : NOTOK;
- } else {
- /* This is OK for a non-message file, it still uses the
- BACKUP_PREFIX form. The backup file will be in the same
- directory as file. */
- return rename (file, m_backup (file));
}
+ /* This is OK for a non-message file, it still uses the
+ BACKUP_PREFIX form. The backup file will be in the same
+ directory as file. */
+ return rename (file, m_backup (file));
}