Removed unnecessary #include of h/signals.h.
[mmh] / uip / mhbuild.c
index cc319f5..2ffd09c 100644 (file)
@@ -15,9 +15,7 @@
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/signals.h>
 #include <errno.h>
-#include <signal.h>
 #include <h/tws.h>
 #include <h/mime.h>
 #include <h/mhparse.h>
 #include <time.h>
 
 static struct swit switches[] = {
-#define EBCDICSW  0
-       { "ebcdicsafe", 0 },
-#define NEBCDICSW  1
-       { "noebcdicsafe", 0 },
-#define HEADSW  2
-       { "headers", 0 },
-#define NHEADSW  3
-       { "noheaders", 0 },
-#define LISTSW  4
-       { "list", 0 },
-#define NLISTSW  5
-       { "nolist", 0 },
-#define RFC934SW  6
-       { "rfc934mode", 0 },
-#define NRFC934SW  7
-       { "norfc934mode", 0 },
-#define VERBSW  8
+#define VERBSW  0
        { "verbose", 0 },
-#define NVERBSW  9
-       { "noverbose", 0 },
-#define CONTENTIDSW  10
-       { "contentid", 0 },
-#define NCONTENTIDSW  11
-       { "nocontentid", 0 },
-#define VERSIONSW  12
-       { "version", 0 },
-#define HELPSW  13
+#define NVERBSW  1
+       { "noverbose", 2 },
+#define VERSIONSW  2
+       { "Version", 0 },
+#define HELPSW  3
        { "help", 0 },
-#define DEBUGSW  14
+#define DEBUGSW  4
        { "debug", -5 },
        { NULL, 0 }
 };
@@ -103,11 +81,6 @@ static CT build_mime(char *);
 int debugsw = 0;
 int verbosw = 0;
 
-int ebcdicsw = 0;
-int listsw   = 0;
-int rfc934sw = 0;
-int contentidsw = 1;
-
 /*
 ** Temporary files
 */
@@ -117,15 +90,12 @@ static int unlink_infile  = 0;
 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 *);
 int output_message_fp(CT, FILE *, char*);
 
-/* mhlistsbr.c */
-int list_all_messages(CT *, int, int, int);
-
 /* mhmisc.c */
 void set_endian(void);
 
@@ -136,19 +106,18 @@ void free_content(CT);
 int
 main(int argc, char **argv)
 {
-       int headsw = 1;
        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 */
@@ -163,7 +132,6 @@ main(int argc, char **argv)
                                adios(NULL, "cannot specify both standard input and a file");
                        else
                                compfile = cp;
-                       listsw = 0;  /* turn off -list if using std in/out */
                        verbosw = 0;  /* turn off -verbose listings */
                        break;
                }
@@ -171,52 +139,18 @@ main(int argc, char **argv)
                        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);
-
-                       case EBCDICSW:
-                               ebcdicsw++;
-                               continue;
-                       case NEBCDICSW:
-                               ebcdicsw = 0;
-                               continue;
-
-                       case HEADSW:
-                               headsw++;
-                               continue;
-                       case NHEADSW:
-                               headsw = 0;
-                               continue;
-
-                       case LISTSW:
-                               listsw++;
-                               continue;
-                       case NLISTSW:
-                               listsw = 0;
-                               continue;
-
-                       case RFC934SW:
-                               rfc934sw++;
-                               continue;
-                       case NRFC934SW:
-                               rfc934sw = 0;
-                               continue;
-
-                       case CONTENTIDSW:
-                               contentidsw = 1;
-                               continue;
-                       case NCONTENTIDSW:
-                               contentidsw = 0;
-                               continue;
+                               exit(0);
 
                        case VERBSW:
                                verbosw++;
@@ -237,9 +171,6 @@ main(int argc, char **argv)
 
        set_endian();
 
-       if ((cp = getenv("MM_NOASK")) && strcmp(cp, "1")==0)
-               listsw  = 0;
-
        /*
        ** Check if we've specified an additional profile
        */
@@ -290,8 +221,6 @@ main(int argc, char **argv)
 
                /* 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),
@@ -316,7 +245,7 @@ main(int argc, char **argv)
                unlink_outfile = 0;
 
                free_content(ct);
-               done(0);
+               exit(0);
        }
 
        /*
@@ -325,8 +254,6 @@ main(int argc, char **argv)
 
        /* 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),
@@ -337,44 +264,38 @@ main(int argc, char **argv)
        output_message_fp(ct, fp_out, outfile);
        fclose(fp_out);
 
-       /*
-       ** List the message info
-       */
-       if (listsw)
-               list_all_messages(cts, headsw, verbosw, debugsw);
-
        /* 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);
+       }
 }
 
 /*
@@ -499,8 +420,10 @@ finish_field:
        ** 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);
@@ -656,7 +579,6 @@ user_content(FILE *in, char *file, char *buf, CT *ctp)
        char buffer[BUFSIZ];
        struct multipart *m;
        struct part **pp;
-       struct stat st;
        struct str2init *s2i;
        CI ci;
        CT ct;
@@ -784,13 +706,12 @@ rock_and_roll:
                        }
                }
 
-               if (listsw)
-                       ct->c_end = ftell(out);
                fclose(out);
 
                /* 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))
@@ -838,7 +759,8 @@ call_init:
 
        /* 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++)
@@ -867,8 +789,8 @@ call_init:
                                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))
@@ -892,8 +814,6 @@ use_forw:
                                ce->ce_file = ci->ci_magic;
                                if (access(ce->ce_file, R_OK) == NOTOK)
                                        adios("reading", "unable to access %s for", ce->ce_file);
-                               if (listsw && stat(ce->ce_file, &st) != NOTOK)
-                                       ct->c_end = (long) st.st_size;
                                ci->ci_magic = NULL;
                        }
                        return OK;
@@ -911,7 +831,8 @@ use_forw:
                        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);
@@ -963,7 +884,8 @@ use_forw:
                        cp = *ap;
                        if (*cp != '+' && *cp != '@')
                                if (!m_convert(mp, cp))
-                                       done(1);
+                                       /* sysexits.h EX_USAGE */
+                                       exit(1);
                }
                free(folder);
                free_ctinfo(ct);
@@ -977,7 +899,8 @@ use_forw:
                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;
 
@@ -1000,7 +923,8 @@ use_forw:
                                        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;
 
@@ -1008,9 +932,6 @@ use_forw:
                                                        "%s/%d", mp->foldpath,
                                                        msgnum);
                                        pe->ce_file = getcpy(buffer);
-                                       if (listsw && stat(pe->ce_file, &st)
-                                                       != NOTOK)
-                                               p->c_end = (long) st.st_size;
 
                                        if ((part = (struct part *) calloc(1, sizeof(*part))) == NULL)
                                                adios(NULL, "out of memory");
@@ -1022,7 +943,8 @@ use_forw:
                } 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;
 
@@ -1030,8 +952,6 @@ use_forw:
                        snprintf(buffer, sizeof(buffer), "%s/%d",
                                        mp->foldpath, msgnum);
                        ce->ce_file = getcpy(buffer);
-                       if (listsw && stat(ce->ce_file, &st) != NOTOK)
-                               ct->c_end = (long) st.st_size;
                }
 
                folder_free(mp);  /* free folder/message structure */
@@ -1070,7 +990,8 @@ use_forw:
                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;
 
@@ -1130,42 +1051,6 @@ set_id(CT ct, int top)
 }
 
 
-static char ebcdicsafe[0x100] = {
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-       0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
 /*
 ** Fill out, or expand the various contents in the composition
 ** draft.  Read-in any necessary files.  Parse and execute any
@@ -1204,41 +1089,6 @@ compose_content(CT ct)
                        if (compose_content(p) == NOTOK)
                                return NOTOK;
                }
-
-               /*
-               ** If the -rfc934mode switch is given, then check all
-               ** the subparts of a multipart/digest.  If they are all
-               ** message/rfc822, then mark this content and all
-               ** subparts with the rfc934 compatibility mode flag.
-               */
-               if (rfc934sw && ct->c_subtype == MULTI_DIGEST) {
-                       int is934 = 1;
-
-                       for (part = m->mp_parts; part; part = part->mp_next) {
-                               CT p = part->mp_part;
-
-                               if (p->c_subtype != MESSAGE_RFC822) {
-                                       is934 = 0;
-                                       break;
-                               }
-                       }
-                       ct->c_rfc934 = is934;
-                       for (part = m->mp_parts; part; part = part->mp_next) {
-                               CT p = part->mp_part;
-
-                               if ((p->c_rfc934 = is934))
-                                       p->c_end++;
-                       }
-               }
-
-               if (listsw) {
-                       ct->c_end = (partnum = strlen(prefix) + 2) + 2;
-                       if (ct->c_rfc934)
-                               ct->c_end += 1;
-
-                       for (part = m->mp_parts; part; part = part->mp_next)
-                               ct->c_end += part->mp_part->c_end + partnum;
-               }
        }
        break;
 
@@ -1372,18 +1222,11 @@ raw:
                        default:
                                fclose(out);
                                if (pidXwait(child_id, NULL))
-                                       done(1);
+                                       /* sysexits.h EX_SOFTWARE */
+                                       exit(1);
                                break;
                        }
                }
-
-               /* Check size of file */
-               if (listsw && ct->c_end == 0L) {
-                       struct stat st;
-
-                       if (stat(ce->ce_file, &st) != NOTOK)
-                               ct->c_end = (long) st.st_size;
-               }
                break;
        }
 
@@ -1408,11 +1251,10 @@ static int
 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 checkebcdic = 0, ebcdicunsafe = 0;  /* check if contains ebcdic unsafe characters */
+       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;
@@ -1459,41 +1301,26 @@ scan_content(CT ct)
                check8bit = 1;
                checkboundary = 1;
                if (ct->c_subtype == TEXT_PLAIN) {
-                       checkebcdic = 0;
                        checklinelen = 0;
                        checklinespace = 0;
                } else {
-                       checkebcdic = ebcdicsw;
                        checklinelen = 1;
                        checklinespace = 1;
                }
                break;
 
-       case CT_APPLICATION:
-               check8bit = 1;
-               checkebcdic = ebcdicsw;
-               checklinelen = 1;
-               checklinespace = 1;
-               checkboundary = 1;
-               break;
-
        case CT_MESSAGE:
                check8bit = 0;
-               checkebcdic = 0;
                checklinelen = 0;
                checklinespace = 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;
-               checkebcdic = 0;
                checklinelen = 0;
                checklinespace = 0;
                checkboundary = 0;
@@ -1509,9 +1336,6 @@ scan_content(CT ct)
                len = strlen(prefix);
 
                while (fgets(buffer, sizeof(buffer) - 1, in)) {
-                       /*
-                       ** Check for 8bit data.
-                       */
                        if (check8bit) {
                                for (cp = buffer; *cp; cp++) {
                                        if (!isascii(*cp)) {
@@ -1519,30 +1343,14 @@ scan_content(CT ct)
                                                /* no need to keep checking */
                                                check8bit = 0;
                                        }
-                                       /*
-                                       ** Check if character is ebcdic-safe.
-                                       ** We only check this if also checking
-                                       ** for 8bit data.
-                                       */
-                                       if (checkebcdic && !ebcdicsafe[*cp & 0xff]) {
-                                               ebcdicunsafe = 1;
-                                               /* no need to keep checking */
-                                               checkebcdic = 0;
-                                       }
                                }
                        }
 
-                       /*
-                       ** 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)) {
@@ -1605,30 +1413,25 @@ scan_content(CT ct)
                        *ep = cp;
                }
 
-               if (contains8bit || ebcdicunsafe || linelen || linespace)
+               if (contains8bit || linelen || linespace)
                        ct->c_encoding = CE_QUOTED;
                else
                        ct->c_encoding = CE_7BIT;
                break;
 
-       case CT_APPLICATION:
-               /* For application type, use base64, except when postscript */
-               if (contains8bit || ebcdicunsafe || 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;
        }
@@ -1670,16 +1473,6 @@ build_headers(CT ct)
        }
 
        /*
-       ** Skip the output of Content-Type, parameters, content
-       ** description and disposition, and Content-ID if the
-       ** content is of type "message" and the rfc934 compatibility
-       ** flag is set (which means we are inside multipart/digest
-       ** and the switch -rfc934mode was given).
-       */
-       if (ct->c_type == CT_MESSAGE && ct->c_rfc934)
-               goto skip_headers;
-
-       /*
        ** output the content type and subtype
        */
        np = getcpy(TYPE_FIELD);
@@ -1729,9 +1522,9 @@ build_headers(CT ct)
        add_header(ct, np, vp);
 
        /*
-       ** output the Content-ID, unless disabled by -nocontentid
+       ** output the Content-ID
        */
-       if (contentidsw && ct->c_id) {
+       if (ct->c_id) {
                np = getcpy(ID_FIELD);
                vp = concat(" ", ct->c_id, NULL);
                add_header(ct, np, vp);
@@ -1755,7 +1548,6 @@ build_headers(CT ct)
                add_header(ct, np, vp);
        }
 
-skip_headers:
        /*
        ** output the Content-Transfer-Encoding
        */