char *textcharset;
} fix_transformations;
-int mhfixmsgsbr (CT *, char *, const fix_transformations *, char *, FILE **);
+int mhfixmsgsbr (CT *, char *, const fix_transformations *, FILE **, char *,
+ FILE **);
static int fix_boundary (CT *, int *);
-static int copy_input_to_output (const char *, const char *, FILE *);
+static int copy_input_to_output (const char *, FILE *, const char *, FILE *);
static int get_multipart_boundary (CT, char **);
static int replace_boundary (CT, char *, char *);
static int fix_types (CT, svector_t, int *);
struct msgs_array msgs = { 0, 0, NULL };
struct msgs *mp = NULL;
CT *ctp;
- FILE *fp, *outfp = NULL;
+ FILE *fp, *infp = NULL, *outfp = NULL;
int using_stdin = 0;
int chgflag = 1;
int status = OK;
advise (NULL, "unable to parse message from file %s", file);
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. */
- if (copy_input_to_output (file, outfile, outfp) != OK) {
- advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
+ /* Something went wrong. Output might be expected, such as if
+ this were run as a filter. Just copy the input to the
+ output. */
+ if ((infp = fopen (file, "r")) == NULL) {
+ adios (file, "unable to open for reading");
}
+
+ if (copy_input_to_output (file, infp, outfile, outfp) != OK) {
+ advise (NULL, "unable to copy message to %s, "
+ "it might be lost\n", outfile);
+ }
+
+ fclose (infp);
+ infp = NULL;
}
}
} else {
if (! folder) {
folder = getfolder (1);
}
- maildir = m_maildir (folder);
+ maildir = mh_xstrdup(m_maildir (folder));
/* chdir so that error messages, esp. from MIME parser, just
refer to the message and not its path. */
char *input_filename =
concat (maildir, "/", msgnam, NULL);
- if (copy_input_to_output (input_filename, outfile,
- outfp) != OK) {
+ if ((infp = fopen (input_filename, "r")) == NULL) {
+ adios (input_filename,
+ "unable to open for reading");
+ }
+
+ if (copy_input_to_output (input_filename, infp,
+ outfile, outfp) != OK) {
advise (NULL,
"unable to copy message to %s, "
"it might be lost\n",
outfile);
}
+
+ fclose (infp);
+ infp = NULL;
free (input_filename);
}
}
if (*cts) {
for (ctp = cts; *ctp; ++ctp) {
- status += mhfixmsgsbr (ctp, maildir, &fx, outfile, &outfp);
+ status += mhfixmsgsbr (ctp, maildir, &fx, &infp, outfile, &outfp);
free_content (*ctp);
if (using_stdin) {
status = 1;
}
+ mh_xfree(maildir);
free (cts);
if (fx.fixtypes != NULL) { svector_free (fx.fixtypes); }
+ if (infp) { fclose (infp); } /* even if stdin */
if (outfp) { fclose (outfp); } /* even if stdout */
free (outfile);
free (file);
*/
int
mhfixmsgsbr (CT *ctp, char *maildir, const fix_transformations *fx,
- char *outfile, FILE **outfp) {
+ FILE **infp, char *outfile, FILE **outfp) {
/* Store input filename in case one of the transformations, i.e.,
fix_boundary(), rewrites to a tmp file. */
char *input_filename = maildir
int message_mods = 0;
int status = OK;
+ /* Though the input file won't need to be opened if everything goes
+ well, do it here just in case there's a failure, and that failure is
+ running out of file descriptors. */
+ if ((*infp = fopen (input_filename, "r")) == NULL) {
+ adios (input_filename, "unable to open for reading");
+ }
+
if (outfile == NULL) {
modify_inplace = 1;
if ((*ctp)->c_file) {
char *tempfile;
+ /* outfp will be closed by the caller */
if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, outfp)) ==
NULL) {
adios (NULL, "unable to create temporary file in %s",
/* Something went wrong. Output might be expected, such
as if this were run as a filter. Just copy the input
to the output. */
- if (copy_input_to_output (input_filename, outfile, *outfp) != OK) {
- advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
+ if (copy_input_to_output (input_filename, *infp, outfile,
+ *outfp) != OK) {
+ advise (NULL, "unable to copy message to %s, it might be lost\n",
+ outfile);
}
}
outfile = NULL;
}
+ fclose (*infp);
+ *infp = NULL;
free (input_filename);
return status;
* might be running as part of a pipeline.
*/
static int
-copy_input_to_output (const char *input_filename, const char *output_filename,
- FILE *outfp) {
- int in = open (input_filename, O_RDONLY);
+copy_input_to_output (const char *input_filename, FILE *infp,
+ const char *output_filename, FILE *outfp) {
+ int in = fileno (infp);
int out = fileno (outfp);
int status = OK;
status = NOTOK;
}
- close (in);
-
return status;
}
be unlinked by free_content (). */
char *tempfile;
+ /* This m_mktemp2() call closes the temp file. */
if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, NULL)) == NULL) {
advise (NULL, "unable to create temporary file in %s",
get_temp_dir());
status = output_message_fp (ct, file, tmp_decoded);
(void) m_unlink (tmp_decoded);
free (tmp_decoded);
+ if (fclose (file)) {
+ admonish (NULL, "unable to close temporary file %s", tempfile);
+ }
return status;
}
fix_filename_param (char *name, char *value, PM *first_pm, PM *last_pm) {
int fixed = 0;
- if (HasPrefix(value, "=?") && HasSuffix(value, "?=")) {
+ if (has_prefix(value, "=?") && has_suffix(value, "?=")) {
/* Looks like an RFC 2047 encoded parameter. */
char decoded[PATH_MAX + 1];