#define VERBSW 0
{ "verbose", 0 },
#define NVERBSW 1
- { "noverbose", 0 },
+ { "noverbose", 2 },
#define VERSIONSW 2
- { "version", 0 },
+ { "Version", 0 },
#define HELPSW 3
{ "help", 0 },
#define DEBUGSW 4
static char outfile[BUFSIZ];
static int unlink_outfile = 0;
-static void unlink_done(int) NORETURN;
+void unlink_done();
/* mhoutsbr.c */
int output_message(CT, char *);
char *cp, buf[BUFSIZ];
char buffer[BUFSIZ], *compfile = NULL;
char **argp, **arguments;
- CT ct, cts[2];
+ CT ct;
FILE *fp = NULL;
FILE *fp_out = NULL;
- done = unlink_done;
+ if (atexit(unlink_done) != 0) {
+ adios(NULL, "atexit failed");
+ }
-#ifdef LOCALE
setlocale(LC_ALL, "");
-#endif
invo_name = mhbasename(argv[0]);
/* read user profile/context */
switch (smatch(++cp, switches)) {
case AMBIGSW:
ambigsw(cp, switches);
- done(1);
+ /* sysexits.h EX_USAGE */
+ exit(1);
case UNKWNSW:
adios(NULL, "-%s unknown", cp);
case HELPSW:
snprintf(buf, sizeof(buf), "%s [switches] file", invo_name);
print_help(buf, switches, 1);
- done(1);
+ exit(0);
case VERSIONSW:
print_version(invo_name);
- done(1);
+ exit(0);
case VERBSW:
verbosw++;
/* build the content structures for MIME message */
ct = build_mime(infile);
- cts[0] = ct;
- cts[1] = NULL;
/* output MIME message to this temporary file */
strncpy(outfile, m_mktemp(invo_name, NULL, &fp_out),
unlink_outfile = 0;
free_content(ct);
- done(0);
+ exit(0);
}
/*
/* build the content structures for MIME message */
ct = build_mime(compfile);
- cts[0] = ct;
- cts[1] = NULL;
/* output MIME message to this temporary file */
strncpy(outfile, m_mktemp2(compfile, invo_name, NULL, &fp_out),
fclose(fp_out);
/* Rename composition draft */
- snprintf(buffer, sizeof(buffer), "%s.orig", m_backup(compfile));
+ snprintf(buffer, sizeof(buffer), "%s.orig", compfile);
if (rename(compfile, buffer) == NOTOK) {
- adios(compfile, "unable to rename comp draft %s to", buffer);
+ adios(buffer, "unable to rename draft %s to", compfile);
}
/* Rename output file to take its place */
if (rename(outfile, compfile) == NOTOK) {
- advise(outfile, "unable to rename output %s to", compfile);
+ advise(compfile, "unable to rename output %s to", outfile);
rename(buffer, compfile);
- done(1);
+ /* sysexits.h EX_IOERR */
+ exit(1);
}
unlink_outfile = 0;
free_content(ct);
- done(0);
- return 1;
+ return 0;
}
-static void
-unlink_done(int status)
+void
+unlink_done()
{
/*
** Check if we need to remove stray temporary files.
*/
- if (unlink_infile)
+ if (unlink_infile) {
unlink(infile);
- if (unlink_outfile)
+ }
+ if (unlink_outfile) {
unlink(outfile);
-
- exit(status);
+ }
}
/*
** draft. So create a multipart/mixed content to hold everything.
** We can remove this later, if it is not needed.
*/
- if (get_ctinfo("multipart/mixed", ct, 0) == NOTOK)
- done(1);
+ if (get_ctinfo("multipart/mixed", ct, 0) == NOTOK) {
+ /* sysexits.h EX_DATAERR */
+ exit(1);
+ }
ct->c_type = CT_MULTIPART;
ct->c_subtype = MULTI_MIXED;
ct->c_file = getcpy(infile);
/* parse content type */
if (get_ctinfo(content, ct, inlineD) == NOTOK)
- done(1);
+ /* sysexits.h EX_USAGE */
+ exit(1);
for (s2i = str2cts; s2i->si_key; s2i++)
if (!mh_strcasecmp(ci->ci_type, s2i->si_key))
/* parse directive */
if (get_ctinfo(buf+1, ct, 1) == NOTOK)
- done(1);
+ /* sysexits.h EX_DATAERR */
+ exit(1);
/* check directive against the list of MIME types */
for (s2i = str2cts; s2i->si_key; s2i++)
adios(NULL, "sorry, \"#%s/%s\" isn't supported", ci->ci_type, ci->ci_subtype);
}
use_forw:
- adios(NULL, "use \"#forw [+folder] [msgs]\" instead of \"#%s/%s\"", ci->ci_type, ci->ci_subtype);
- /* NOTREACHED */
+ admonish(NULL, "use \"#forw [+folder] [msgs]\" instead of \"#%s/%s\"", ci->ci_type, ci->ci_subtype);
+ /* FALL */
default:
if ((ct->c_ctinitfnx = s2i->si_init))
if ((cp = context_find(buffer)) == NULL ||
*cp == '\0') {
content_error(NULL, ct, "don't know how to compose content");
- done(1);
+ /* sysexits.h EX_USAGE */
+ exit(1);
}
}
ci->ci_magic = getcpy(cp);
cp = *ap;
if (*cp != '+' && *cp != '@')
if (!m_convert(mp, cp))
- done(1);
+ /* sysexits.h EX_USAGE */
+ exit(1);
}
free(folder);
free_ctinfo(ct);
if (mp->numsel > 1) {
/* we are forwarding multiple messages */
if (get_ctinfo("multipart/digest", ct, 0) == NOTOK)
- done(1);
+ /* sysexits.h EX_DATAERR */
+ exit(1);
ct->c_type = CT_MULTIPART;
ct->c_subtype = MULTI_DIGEST;
pe = p->c_cefile;
if (get_ctinfo("message/rfc822", p, 0)
== NOTOK)
- done(1);
+ /* sysexits.h EX_DATAERR */
+ exit(1);
p->c_type = CT_MESSAGE;
p->c_subtype = MESSAGE_RFC822;
} else {
/* we are forwarding one message */
if (get_ctinfo("message/rfc822", ct, 0) == NOTOK)
- done(1);
+ /* sysexits.h EX_DATAERR */
+ exit(1);
ct->c_type = CT_MESSAGE;
ct->c_subtype = MESSAGE_RFC822;
free_ctinfo(ct);
snprintf(buffer, sizeof(buffer), "multipart/%s", cp);
if (get_ctinfo(buffer, ct, 0) == NOTOK)
- done(1);
+ /* sysexits.h EX_DATAERR */
+ exit(1);
ct->c_type = CT_MULTIPART;
ct->c_subtype = vrsn;
default:
fclose(out);
if (pidXwait(child_id, NULL))
- done(1);
+ /* sysexits.h EX_SOFTWARE */
+ exit(1);
break;
}
}
scan_content(CT ct)
{
int len;
- int check8bit = 0, contains8bit = 0; /* check if contains 8bit data */
- int checklinelen = 0, linelen = 0; /* check for long lines */
- int checkboundary = 0, boundaryclash = 0; /* check if clashes with multipart boundary */
- int checklinespace = 0, linespace = 0; /* check if any line ends with space */
+ int check8bit = 0, contains8bit = 0;
+ int checklinelen = 0, linelen = 0;
+ int checkboundary = 0, boundaryclash = 0;
+ int checklinespace = 0, linespace = 0; /* trailing whitespace */
unsigned char *cp = NULL, buffer[BUFSIZ];
struct text *t = NULL;
FILE *in = NULL;
}
break;
- case CT_APPLICATION:
- check8bit = 1;
- checklinelen = 1;
- checklinespace = 1;
- checkboundary = 1;
- break;
-
case CT_MESSAGE:
check8bit = 0;
checklinelen = 0;
checkboundary = 1;
break;
+ case CT_APPLICATION:
case CT_AUDIO:
case CT_IMAGE:
case CT_VIDEO:
- /*
- ** Don't check anything for these types,
- ** since we are forcing use of base64.
- */
check8bit = 0;
checklinelen = 0;
checklinespace = 0;
len = strlen(prefix);
while (fgets(buffer, sizeof(buffer) - 1, in)) {
- /*
- ** Check for 8bit data.
- */
if (check8bit) {
for (cp = buffer; *cp; cp++) {
if (!isascii(*cp)) {
}
}
- /*
- ** Check line length.
- */
if (checklinelen && (strlen(buffer) > CPERLIN + 1)) {
linelen = 1;
checklinelen = 0; /* no need to keep checking */
}
- /*
- ** Check if line ends with a space.
- */
if (checklinespace &&
(cp = buffer + strlen(buffer) - 2) >
buffer && isspace(*cp)) {
ct->c_encoding = CE_7BIT;
break;
- case CT_APPLICATION:
- /* For application type, use base64, except when postscript */
- if (contains8bit || linelen || linespace)
- ct->c_encoding = (ct->c_subtype ==
- APPLICATION_POSTSCRIPT) ?
- CE_QUOTED : CE_BASE64;
- else
- ct->c_encoding = CE_7BIT;
- break;
-
case CT_MESSAGE:
ct->c_encoding = CE_7BIT;
break;
+ case CT_APPLICATION:
case CT_AUDIO:
case CT_IMAGE:
case CT_VIDEO:
- /* For audio, image, and video contents, just use base64 */
+ /*
+ ** Forcing use of base64, because these types likely
+ ** contain binary data and NUL bytes. Don't care about
+ ** files that would be clean.
+ */
ct->c_encoding = CE_BASE64;
break;
}