/* 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;
if (nmh_init(argv[0], 2)) { return 1; }
- done = freects_done;
-
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
}
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");
}
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;
}
ct->c_celine = add (cte, NULL);
return OK;
- } else {
- return NOTOK;
}
+
+ return NOTOK;
}
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;
}
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 {
*/
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) {
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));
}