]> diplodocus.org Git - nmh/blobdiff - uip/mhstoresbr.c
Newer versions of Automake want to include the test-driver script,
[nmh] / uip / mhstoresbr.c
index 89a2f27854fe4a1d89481f72a1e26a76eb5ab02d..62a5ba43b19fa43e7125a0254545ad0b4d1f9ef2 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/signals.h>
 #include <h/md5.h>
 #include <h/mts.h>
 #include <h/tws.h>
@@ -41,8 +40,6 @@ struct mhstoreinfo {
     enum clobber_policy_t clobber_policy;  /* -clobber selection */
 };
 
-typedef struct mhstoreinfo *mhstoreinfo_t;
-
 mhstoreinfo_t
 mhstoreinfo_create (CT *ct, char *pwd, const char *csw, int asw, int vsw) {
     mhstoreinfo_t info = mh_xmalloc (sizeof *info);
@@ -61,6 +58,7 @@ mhstoreinfo_create (CT *ct, char *pwd, const char *csw, int asw, int vsw) {
 void
 mhstoreinfo_free (mhstoreinfo_t info) {
     free (info->cwd);
+    free (info->dir);
     free (info);
 }
 
@@ -78,18 +76,10 @@ typedef int (*qsort_comp) (const void *, const void *);
 
 
 /* mhmisc.c */
-int part_ok (CT, int);
+int part_ok (CT);
 int type_ok (CT, int);
 void flush_errors (void);
 
-/* mhshowsbr.c */
-int show_content_aux (CT, int, int, char *, char *);
-
-/*
- * prototypes
- */
-void store_all_messages (mhstoreinfo_t);
-
 /*
  * static prototypes
  */
@@ -184,6 +174,7 @@ store_switch (CT ct, mhstoreinfo_t info)
            }
 
        case CT_APPLICATION:
+       default:
            return store_application (ct, info);
 
        case CT_TEXT:
@@ -191,9 +182,6 @@ store_switch (CT ct, mhstoreinfo_t info)
        case CT_IMAGE:
        case CT_VIDEO:
            return store_generic (ct, info);
-
-       default:
-           adios (NULL, "unknown content type %d", ct->c_type);
     }
 
     return OK; /* NOT REACHED */
@@ -227,7 +215,6 @@ store_generic (CT ct, mhstoreinfo_t info)
 static int
 store_application (CT ct, mhstoreinfo_t info)
 {
-    char **ap, **ep;
     CI ci = &ct->c_ctinfo;
 
     /* Check if the content specifies a filename */
@@ -241,28 +228,23 @@ store_application (CT ct, mhstoreinfo_t info)
      */
     if (!ct->c_storeproc && ct->c_subtype == APPLICATION_OCTETS) {
        int tarP = 0, zP = 0, gzP = 0;
+       char *cp;
 
-       for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-           /* check for "type=tar" attribute */
-           if (!strcasecmp (*ap, "type")) {
-               if (strcasecmp (*ep, "tar"))
-                   break;
-
+       if ((cp = get_param(ci->ci_first_pm, "type", ' ', 1))) {
+           if (strcasecmp (cp, "tar") == 0)
                tarP = 1;
-               continue;
-           }
+       }
 
-           /* check for "conversions=compress" attribute */
-           if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
-               && (!strcasecmp (*ep, "compress") || !strcasecmp (*ep, "x-compress"))) {
+       /* check for "conversions=compress" attribute */
+       if ((cp = get_param(ci->ci_first_pm, "conversions", ' ', 1)) ||
+           (cp = get_param(ci->ci_first_pm, "x-conversions", ' ', 1))) {
+           if (strcasecmp (cp, "compress") == 0 ||
+                   strcasecmp (cp, "x-compress") == 0) {
                zP = 1;
-               continue;
            }
-           /* check for "conversions=gzip" attribute */
-           if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
-               && (!strcasecmp (*ep, "gzip") || !strcasecmp (*ep, "x-gzip"))) {
+           if (strcasecmp (cp, "gzip") == 0 ||
+                   strcasecmp (cp, "x-gzip") == 0) {
                gzP = 1;
-               continue;
            }
        }
 
@@ -304,15 +286,14 @@ store_multi (CT ct, mhstoreinfo_t info)
     for (part = m->mp_parts; part; part = part->mp_next) {
        CT  p = part->mp_part;
 
-       if (part_ok (p, 1) && type_ok (p, 1)) {
+       if (part_ok (p) && type_ok (p, 1)) {
            if (ct->c_storage) {
                /* Support mhstore -outfile.  The MIME parser doesn't
                   load c_storage, so we know that p->c_storage is
                   NULL here. */
-               p->c_storage = ct->c_storage;
+               p->c_storage = add (ct->c_storage, NULL);
            }
            result = store_switch (p, info);
-           p->c_storage = NULL;
 
            if (result == OK && ct->c_subtype == MULTI_ALTERNATE)
                break;
@@ -363,7 +344,7 @@ store_partial (CT ct, mhstoreinfo_t info)
        return NOTOK;
     }
 
-    if ((base = (CT *) calloc ((size_t) (i + 1), sizeof(*base))) == NULL)
+    if ((base = (CT *) mh_xcalloc ((size_t) (i + 1), sizeof(*base))) == NULL)
        adios (NULL, "out of memory");
 
     ctq = base;
@@ -476,10 +457,9 @@ store_external (CT ct, mhstoreinfo_t info)
     if (ct->c_storage) {
        /* Support mhstore -outfile.  The MIME parser doesn't load
           c_storage, so we know that p->c_storage is NULL here. */
-       p->c_storage = ct->c_storage;
+       p->c_storage = add (ct->c_storage, NULL);
     }
     result = store_switch (p, info);
-    p->c_storage = NULL;
 
     p->c_partno = NULL;
     return result;
@@ -577,13 +557,9 @@ store_content (CT ct, CT p, mhstoreinfo_t info)
     if ((cp = ct->c_storeproc) == NULL || *cp == '\0') {
        CI ci = &ct->c_ctinfo;
 
-       snprintf (buffer, sizeof(buffer), "%s-store-%s/%s",
-               invo_name, ci->ci_type, ci->ci_subtype);
-       if ((cp = context_find (buffer)) == NULL || *cp == '\0') {
-           snprintf (buffer, sizeof(buffer), "%s-store-%s", invo_name, ci->ci_type);
-           if ((cp = context_find (buffer)) == NULL || *cp == '\0') {
-               cp = ct->c_type == CT_MESSAGE ? "+" : "%m%P.%s";
-           }
+       cp = context_find_by_type ("store", ci->ci_type, ci->ci_subtype);
+       if (cp == NULL) {
+           cp = ct->c_type == CT_MESSAGE ? "+" : "%m%P.%s";
        }
     }
 
@@ -631,7 +607,7 @@ store_content (CT ct, CT p, mhstoreinfo_t info)
         * content to standard input of a command and return.
         */
        if (buffer[0] == '|' || buffer[0] == '!')
-           return show_content_aux (ct, 1, 0, buffer + 1, info->dir);
+           return show_content_aux (ct, 0, buffer + 1, info->dir, NULL);
 
         /* record the filename */
        if ((ct->c_storage = clobber_check (add (buffer, NULL), info)) ==
@@ -640,7 +616,7 @@ store_content (CT ct, CT p, mhstoreinfo_t info)
        }
     } else {
        /* The output filename was explicitly specified, so use it. */
-       if ((ct->c_storage = clobber_check (add (ct->c_storage, NULL), info)) ==
+       if ((ct->c_storage = clobber_check (ct->c_storage, info)) ==
            NULL) {
            return NOTOK;
        }
@@ -798,7 +774,9 @@ losing:
                    break;
 
                default:
-                   fwrite (buffer, sizeof(*buffer), cc, fp);
+                   if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+                       advise ("output_content_file", "fwrite");
+                   }
                    continue;
            }
            break;
@@ -998,12 +976,12 @@ parse_format_string (CT ct, char *cp, char *buffer, int buflen, char *dir)
                        buflen--;
                        continue;
                    } else {
-                       char **ap, **ep;
+                       PM pm;
                        char *s = "";
 
-                       for (ap = ci->ci_attrs, ep = ci->ci_values;
-                                *ap; ap++, ep++) {
-                           snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep);
+                       for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+                           snprintf (bp, buflen, "%s%s=\"%s\"", s,
+                                     pm->pm_name, get_param_value(pm, '?'));
                            len = strlen (bp);
                            bp += len;
                            buflen -= len;
@@ -1075,7 +1053,7 @@ raw:
 static void
 get_storeproc (CT ct)
 {
-    char **ap, **ep, *cp;
+    char *cp;
     CI ci;
 
     /*
@@ -1091,29 +1069,18 @@ get_storeproc (CT ct)
      * use that (RFC-2183).
      */
     if (ct->c_dispo) {
-       char *cp = strchr (ct->c_dispo, ';');
-       CI ci = calloc (1, sizeof *ci);
-       int status;
-       int found_filename = 0;
-
-       if (cp  &&  parse_header_attrs (ct->c_file, strlen (invo_name) + 2, &cp,
-                                        ci, &status) == OK) {
-           for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-               if (! strcasecmp (*ap, "filename")
-                   && *(cp = *ep) != '/'
-                   && *cp != '.'
-                   && *cp != '|'
-                   && *cp != '!'
-                   && !strchr (cp, '%')) {
-                   ct->c_storeproc = add (cp, NULL);
-                   found_filename = 1;
-               }
-               free (*ap);
-           }
+       if ((cp = get_param(ct->c_dispo_first, "filename", '_', 0))
+               && *cp != '/'
+               && *cp != '.'
+               && *cp != '|'
+               && *cp != '!'
+               && !strchr (cp, '%')) {
+               ct->c_storeproc = add (cp, NULL);
+               free(cp);
+               return;
        }
-
-       free (ci);
-       if (found_filename) return;
+       if (cp)
+           free(cp);
     }
 
     /*
@@ -1122,17 +1089,17 @@ get_storeproc (CT ct)
      * the storeproc.
      */
     ci = &ct->c_ctinfo;
-    for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-       if (! strcasecmp (*ap, "name")
-           && *(cp = *ep) != '/'
-           && *cp != '.'
-           && *cp != '|'
-           && *cp != '!'
-           && !strchr (cp, '%')) {
+    if ((cp = get_param(ci->ci_first_pm, "name", '_', 0))
+         && *cp != '/'
+         && *cp != '.'
+         && *cp != '|'
+         && *cp != '!'
+         && !strchr (cp, '%')) {
            ct->c_storeproc = add (cp, NULL);
-           return;
-       }
+
     }
+    if (cp)
+       free(cp);
 }
 
 
@@ -1264,6 +1231,10 @@ clobber_check (char *original_file, mhstoreinfo_t info) {
   char *cwd = NULL;
   int check_again;
 
+  if (! strcmp (original_file, "-")) {
+      return original_file;
+  }
+
   if (info->clobber_policy == NMH_CLOBBER_ASK) {
     /* Save cwd for possible use in loop below. */
     char *slash;
@@ -1274,7 +1245,9 @@ clobber_check (char *original_file, mhstoreinfo_t info) {
     if (slash) {
       *slash = '\0';
     } else {
-      /* original_file wasn't a full path, which shouldn't happen. */
+      /* original_file isn't a full path, which should only happen if
+         it is -. */
+      free (cwd);
       cwd = NULL;
     }
   }
@@ -1312,7 +1285,7 @@ clobber_check (char *original_file, mhstoreinfo_t info) {
           if (isatty (fileno (stdin))) {
             char *prompt =
               concat ("Overwrite \"", file, "\" [y/n/rename]? ", NULL);
-            ans = getans (prompt, answer);
+            ans = read_switch_multiword (prompt, answer);
             free (prompt);
           } else {
             /* Overwrite, that's what nmh used to do.  And warn. */
@@ -1374,9 +1347,7 @@ clobber_check (char *original_file, mhstoreinfo_t info) {
     original_file = file;
   } while (check_again);
 
-  if (cwd) {
-    free (cwd);
-  }
+  free (cwd);
 
   return file;
 }