]> diplodocus.org Git - nmh/blobdiff - uip/mhbuildsbr.c
Beginning of implementation of new argsplit() function to handle arguments
[nmh] / uip / mhbuildsbr.c
index d417befde88f6ac826a31ca7ed6e17acb1089a0e..653c5b3f380d926a6a07a313cf9789da91a29c95 100644 (file)
 extern int debugsw;
 extern int verbosw;
 
-extern int ebcdicsw;
 extern int listsw;
 extern int rfc934sw;
 extern int contentidsw;
 
-extern int endian;     /* mhmisc.c */
-
 /* cache policies */
 extern int rcachesw;   /* mhcachesbr.c */
 extern int wcachesw;   /* mhcachesbr.c */
@@ -59,7 +56,6 @@ static char prefix[] = "----- =_aaaaaaaaaa";
 
 
 /* mhmisc.c */
-int make_intermediates (char *);
 void content_error (char *, CT, char *, ...);
 
 /* mhcachesbr.c */
@@ -73,7 +69,7 @@ void free_encoding (CT, int);
 /*
  * prototypes
  */
-CT build_mime (char *);
+CT build_mime (char *, int);
 
 /*
  * static prototypes
@@ -88,6 +84,37 @@ static int build_headers (CT);
 static char *calculate_digest (CT, int);
 
 
+static unsigned char directives_stack[32];
+static unsigned int directives_index;
+
+static int do_direct(void)
+{
+    return directives_stack[directives_index];
+}
+
+static void directive_onoff(int onoff)
+{
+    if (directives_index >= sizeof(directives_stack) - 1) {
+       fprintf(stderr, "mhbuild: #on/off overflow, continuing\n");
+       return;
+    }
+    directives_stack[++directives_index] = onoff;
+}
+
+static void directive_init(int onoff)
+{
+    directives_index = 0;
+    directives_stack[0] = onoff;
+}
+
+static void directive_pop(void)
+{
+    if (directives_index > 0)
+       directives_index--;
+    else
+       fprintf(stderr, "mhbuild: #pop underflow, continuing\n");
+}
+
 /*
  * Main routine for translating composition file
  * into valid MIME message.  It translates the draft
@@ -98,7 +125,7 @@ static char *calculate_digest (CT, int);
  */
 
 CT
-build_mime (char *infile)
+build_mime (char *infile, int directives)
 {
     int        compnum, state;
     char buf[BUFSIZ], name[NAMESZ];
@@ -108,6 +135,8 @@ build_mime (char *infile)
     CT ct;
     FILE *in;
 
+    directive_init(directives);
+
     umask (~m_gmprot ());
 
     /* open the composition draft */
@@ -328,20 +357,34 @@ static char *
 fgetstr (char *s, int n, FILE *stream)
 {
     char *cp, *ep;
+    int o_n = n;
+
+    while(1) {
+       for (ep = (cp = s) + o_n; cp < ep; ) {
+           int i;
 
-    for (ep = (cp = s) + n; cp < ep; ) {
-       int i;
+           if (!fgets (cp, n, stream))
+               return (cp != s ? s : NULL);
 
-       if (!fgets (cp, n, stream))
-           return (cp != s ? s : NULL);
-       if (cp == s && *cp != '#')
-           return s;
+           if (cp == s && *cp != '#')
+               return s;
+
+           cp += (i = strlen (cp)) - 1;
+           if (i <= 1 || *cp-- != '\n' || *cp != '\\')
+               break;
+           *cp = '\0';
+           n -= (i - 2);
+       }
 
-       cp += (i = strlen (cp)) - 1;
-       if (i <= 1 || *cp-- != '\n' || *cp != '\\')
+       if (strcmp(s, "#on\n") == 0) {
+           directive_onoff(1);
+       } else if (strcmp(s, "#off\n") == 0) {
+           directive_onoff(0);
+       } else if (strcmp(s, "#pop\n") == 0) {
+           directive_pop();
+       } else {
            break;
-       *cp = '\0';
-       n -= (i - 2);
+       }
     }
 
     return s;
@@ -368,7 +411,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp)
     CT ct;
     CE ce;
 
-    if (buf[0] == '\n' || strcmp (buf, "#\n") == 0) {
+    if (buf[0] == '\n' || (do_direct() && strcmp (buf, "#\n") == 0)) {
        *ctp = NULL;
        return OK;
     }
@@ -393,7 +436,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp)
      * 2) begins with "##"             (implicit directive)
      * 3) begins with "#<"
      */
-    if (buf[0] != '#' || buf[1] == '#' || buf[1] == '<') {
+    if (!do_direct() || buf[0] != '#' || buf[1] == '#' || buf[1] == '<') {
        int headers;
        int inlineD;
        long pos;
@@ -408,7 +451,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp)
        ce->ce_file = add (cp, NULL);
        ce->ce_unlink = 1;
 
-       if (buf[0] == '#' && buf[1] == '<') {
+       if (do_direct() && (buf[0] == '#' && buf[1] == '<')) {
            strncpy (content, buf + 2, sizeof(content));
            inlineD = 1;
            goto rock_and_roll;
@@ -419,11 +462,11 @@ user_content (FILE *in, char *file, char *buf, CT *ctp)
        /* the directive is implicit */
        strncpy (content, "text/plain", sizeof(content));
        headers = 0;
-       strncpy (buffer, buf[0] != '#' ? buf : buf + 1, sizeof(buffer));
+       strncpy (buffer, (!do_direct() || buf[0] != '#') ? buf : buf + 1, sizeof(buffer));
        for (;;) {
            int i;
 
-           if (headers >= 0 && uprf (buffer, DESCR_FIELD)
+           if (headers >= 0 && do_direct() && uprf (buffer, DESCR_FIELD)
                && buffer[i = strlen (DESCR_FIELD)] == ':') {
                headers = 1;
 
@@ -446,7 +489,7 @@ again_descr:
                }
            }
 
-           if (headers >= 0 && uprf (buffer, DISPO_FIELD)
+           if (headers >= 0 && do_direct() && uprf (buffer, DISPO_FIELD)
                && buffer[i = strlen (DISPO_FIELD)] == ':') {
                headers = 1;
 
@@ -477,7 +520,7 @@ rock_and_roll:
            pos = ftell (in);
            if ((cp = fgetstr (buffer, sizeof(buffer) - 1, in)) == NULL)
                break;
-           if (buffer[0] == '#') {
+           if (do_direct() && buffer[0] == '#') {
                char *bp;
 
                if (buffer[1] != '#')
@@ -851,59 +894,22 @@ use_forw:
 static void
 set_id (CT ct, int top)
 {
-    char msgid[BUFSIZ];
+    char contentid[BUFSIZ];
     static int partno;
     static time_t clock = 0;
     static char *msgfmt;
 
     if (clock == 0) {
        time (&clock);
-       snprintf (msgid, sizeof(msgid), "<%d.%ld.%%d@%s>\n",
-               (int) getpid(), (long) clock, LocalName());
+       snprintf (contentid, sizeof(contentid), "%s\n", message_id (clock, 1));
        partno = 0;
-       msgfmt = getcpy(msgid);
+       msgfmt = getcpy(contentid);
     }
-    snprintf (msgid, sizeof(msgid), msgfmt, top ? 0 : ++partno);
-    ct->c_id = getcpy (msgid);
+    snprintf (contentid, sizeof(contentid), msgfmt, top ? 0 : ++partno);
+    ct->c_id = getcpy (contentid);
 }
 
 
-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
@@ -1087,7 +1093,7 @@ raw:
            if ((out = fopen (ce->ce_file, "w")) == NULL)
                adios (ce->ce_file, "unable to open for writing");
 
-           for (i = 0; (child_id = m_vfork()) == NOTOK && i > 5; i++)
+           for (i = 0; (child_id = vfork()) == NOTOK && i > 5; i++)
                sleep (5);
            switch (child_id) {
            case NOTOK:
@@ -1147,7 +1153,6 @@ scan_content (CT ct)
     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 */
     unsigned char *cp = NULL, buffer[BUFSIZ];
     struct text *t = NULL;
     FILE *in = NULL;
@@ -1188,11 +1193,9 @@ 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;
        }
@@ -1200,7 +1203,6 @@ scan_content (CT ct)
 
     case CT_APPLICATION:
        check8bit = 1;
-       checkebcdic = ebcdicsw;
        checklinelen = 1;
        checklinespace = 1;
        checkboundary = 1;
@@ -1208,7 +1210,6 @@ scan_content (CT ct)
 
     case CT_MESSAGE:
        check8bit = 0;
-       checkebcdic = 0;
        checklinelen = 0;
        checklinespace = 0;
 
@@ -1227,7 +1228,6 @@ scan_content (CT ct)
         * since we are forcing use of base64.
         */
        check8bit = 0;
-       checkebcdic = 0;
        checklinelen = 0;
        checklinespace = 0;
        checkboundary = 0;
@@ -1252,14 +1252,6 @@ scan_content (CT ct)
                        contains8bit = 1;
                        check8bit = 0;  /* no need to keep checking */
                    }
-                   /*
-                    * Check if character is ebcdic-safe.  We only check
-                    * this if also checking for 8bit data.
-                    */
-                   if (checkebcdic && !ebcdicsafe[*cp & 0xff]) {
-                       ebcdicunsafe = 1;
-                       checkebcdic = 0; /* no need to keep checking */
-                   }
                }
            }
 
@@ -1315,12 +1307,11 @@ scan_content (CT ct)
                continue;
 
            if (contains8bit) {
-               t->tx_charset = CHARSET_UNKNOWN;
                *ap = concat ("charset=", write_charset_8bit(), NULL);
            } else {
-               t->tx_charset = CHARSET_USASCII;
                *ap = add ("charset=us-ascii", NULL);
            }
+           t->tx_charset = CHARSET_SPECIFIED;
 
            cp = strchr(*ap++, '=');
            *ap = NULL;
@@ -1328,7 +1319,7 @@ scan_content (CT ct)
            *ep = cp;
        }
 
-       if (contains8bit || ebcdicunsafe || linelen || linespace || checksw)
+       if (contains8bit || linelen || linespace || checksw)
            ct->c_encoding = CE_QUOTED;
        else
            ct->c_encoding = CE_7BIT;
@@ -1336,7 +1327,7 @@ scan_content (CT ct)
 
     case CT_APPLICATION:
        /* For application type, use base64, except when postscript */
-       if (contains8bit || ebcdicunsafe || linelen || linespace || checksw)
+       if (contains8bit || linelen || linespace || checksw)
            ct->c_encoding = (ct->c_subtype == APPLICATION_POSTSCRIPT)
                ? CE_QUOTED : CE_BASE64;
        else
@@ -1507,11 +1498,6 @@ skip_headers:
     switch (ct->c_encoding) {
     case CE_7BIT:
        /* Nothing to output */
-#if 0
-       np = add (ENCODING_FIELD, NULL);
-       vp = concat (" ", "7bit", "\n", NULL);
-       add_header (ct, np, vp);
-#endif
        break;
 
     case CE_8BIT:
@@ -1603,13 +1589,14 @@ calculate_digest (CT ct, int asciiP)
     unsigned char *dp;
     unsigned char digest[16];
     unsigned char outbuf[25];
-    FILE *in;
     MD5_CTX mdContext;
     CE ce = ct->c_cefile;
+    char *infilename = ce->ce_file ? ce->ce_file : ct->c_file;
+    FILE *in;
 
     /* open content */
-    if ((in = fopen (ce->ce_file, "r")) == NULL)
-       adios (ce->ce_file, "unable to open for reading");
+    if ((in = fopen (infilename, "r")) == NULL)
+       adios (infilename, "unable to open for reading");
 
     /* Initialize md5 context */
     MD5Init (&mdContext);