]> diplodocus.org Git - nmh/commitdiff
Added -outfile switch to mhstore(1).
authorDavid Levine <levinedl@acm.org>
Sun, 28 Apr 2013 16:29:47 +0000 (11:29 -0500)
committerDavid Levine <levinedl@acm.org>
Sun, 28 Apr 2013 16:29:47 +0000 (11:29 -0500)
docs/pending-release-notes
man/mhstore.man
test/mhstore/test-mhstore
uip/mhstore.c
uip/mhstoresbr.c

index c71cf1e..64b1d71 100644 (file)
@@ -24,6 +24,7 @@ NEW FEATURES
   (pseudo)random bytes and uses microsecond-resolution time.
 - Added -clobber switch to mhstore(1) to control overwriting of
   existing files.
+- Added -outfile switch to mhstore(1).
 - Added -noall/-all switches to sortm(1).  sortm -noall requires
   a messages argument.
 - $PAGER overrides the compiled-in default pager command.
index 691abac..d39994e 100644 (file)
@@ -12,6 +12,8 @@ mhstore \- store contents of MIME messages into files
 .RI [ msgs ]
 .RB [ \-file
 .IR file ]
+.RB [ \-outfile
+.IR outfile ]
 .RB [ \-part
 .IR number ]
 \&...
@@ -53,10 +55,10 @@ switches, you may limit the scope of
 to particular
 subparts (of a multipart content) and/or particular content types.
 .PP
-The option
+The
 .B \-file
 .I file
-directs
+switch directs
 .B mhstore
 to use the specified
 file as the source message, rather than a message from a folder.
@@ -154,6 +156,9 @@ If this entry isn't present,
 the current working directory is used.
 .PP
 If the
+.B \-outfile
+switch is given, its argument is used for the filename to store the
+content, with \*(lq-\*(rq indicating standard output.  If the
 .B \-auto
 switch is given, then
 .B mhstore
@@ -336,6 +341,12 @@ terminal,
 .I ask
 behaves the same as
 .IR always .
+.PP
+The
+.B \-clobber
+switch is ignored if the
+.B \-outfile
+switch is used.
 .SS "Reassembling Messages of Type message/partial"
 .B mhstore
 is also able to reassemble messages that have been
index d509abe..b332cd9 100755 (executable)
@@ -16,8 +16,8 @@ fi
 
 setup_test
 
-expected=$MH_TEST_DIR/$$.expected
-actual=$MH_TEST_DIR/$$.actual
+expected="$MH_TEST_DIR/test-mhstore$$.expected"
+actual="$MH_TEST_DIR/test-mhstore$$.actual"
 
 cd $MH_TEST_DIR
 
@@ -48,7 +48,18 @@ check $expected 5.txt 'keep first'
 # check -file -
 stored_contents=`mhstore -file - < $MH_TEST_DIR/Mail/inbox/5 2>&1 | \
   sed 's/.*as file //'`
-check $expected $stored_contents
+check $expected $stored_contents 'keep first'
+
+# check -outfile
+set +e
+mhstore 5 -outfile "$actual" 2>&1 | grep -v '^storing'
+set -e
+check $expected "$actual" 'keep first'
+
+# check -outfile -
+echo 'storing message 5 to stdout' >> "$expected"
+mhstore 5 -outfile - >"$actual" 2>&1
+check $expected "$actual"
 
 # check message number greater than highest
 run_test 'mhstore 11' "mhstore: message 11 doesn't exist"
index ff18533..79f335e 100644 (file)
@@ -26,6 +26,7 @@
     X("verbose", 0, VERBSW) \
     X("noverbose", 0, NVERBSW) \
     X("file file", 0, FILESW)          /* interface from show */ \
+    X("outfile outfile", 0, OUTFILESW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
     X("rcache policy", 0, RCACHESW) \
@@ -97,7 +98,7 @@ int
 main (int argc, char **argv)
 {
     int msgnum, *icachesw;
-    char *cp, *file = NULL, *folder = NULL;
+    char *cp, *file = NULL, *outfile = NULL, *folder = NULL;
     char *maildir, buf[100], **argp;
     char **arguments;
     struct msgs_array msgs = { 0, 0, NULL };
@@ -196,6 +197,12 @@ do_cache:
                file = *cp == '-' ? cp : path (cp, TFILE);
                continue;
 
+           case OUTFILESW:
+               if (!(cp = *argp++) || (*cp == '-' && cp[1]))
+                   adios (NULL, "missing argument to %s", argp[-2]);
+               outfile = *cp == '-' ? cp : path (cp, TFILE);
+               continue;
+
            case VERBSW: 
                verbosw = 1;
                continue;
@@ -286,8 +293,12 @@ do_cache:
            adios (NULL, "out of memory");
        ctp = cts;
 
-       if ((ct = parse_mime (file)))
+       if ((ct = parse_mime (file))) {
            *ctp++ = ct;
+           if (outfile) {
+               ct->c_storage = outfile;
+           }
+        }
     } else {
        /*
         * message(s) are coming from a folder
@@ -324,8 +335,12 @@ do_cache:
                char *msgnam;
 
                msgnam = m_name (msgnum);
-               if ((ct = parse_mime (msgnam)))
+               if ((ct = parse_mime (msgnam))) {
                    *ctp++ = ct;
+                   if (outfile) {
+                       ct->c_storage = add (outfile, NULL);
+                   }
+                }
            }
        }
     }
index 4d26b57..fab1680 100644 (file)
@@ -278,7 +278,15 @@ store_multi (CT ct)
        CT  p = part->mp_part;
 
        if (part_ok (p, 1) && 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;
+           }
            result = store_switch (p);
+           p->c_storage = NULL;
+
            if (result == OK && ct->c_subtype == MULTI_ALTERNATE)
                break;
        }
@@ -438,7 +446,13 @@ store_external (CT ct)
     p->c_partno = ct->c_partno;
 
     /* we probably need to check if content is really there */
+    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;
+    }
     result = store_switch (p);
+    p->c_storage = NULL;
 
     p->c_partno = NULL;
     return result;
@@ -512,11 +526,13 @@ store_content (CT ct, CT p)
         */
        if (p) {
            appending = 1;
-           ct->c_storage = add (p->c_storage, NULL);
+            if (! ct->c_storage) {
+               ct->c_storage = add (p->c_storage, NULL);
 
-           /* record the folder name */
-           if (p->c_folder) {
-               ct->c_folder = add (p->c_folder, NULL);
+               /* record the folder name */
+               if (p->c_folder) {
+                   ct->c_folder = add (p->c_folder, NULL);
+               }
            }
            goto got_filename;
        }
@@ -544,52 +560,54 @@ store_content (CT ct, CT p)
        }
     }
 
-    /*
-     * Check the beginning of storage formatting string
-     * to see if we are saving content to a folder.
-     */
-    if (*cp == '+' || *cp == '@') {
-       char *tmpfilenam, *folder;
+    if (! ct->c_storage) {
+       /*
+        * Check the beginning of storage formatting string
+        * to see if we are saving content to a folder.
+        */
+       if (*cp == '+' || *cp == '@') {
+           char *tmpfilenam, *folder;
 
-       /* Store content in temporary file for now */
-       tmpfilenam = m_mktemp(invo_name, NULL, NULL);
-       ct->c_storage = add (tmpfilenam, NULL);
+           /* Store content in temporary file for now */
+           tmpfilenam = m_mktemp(invo_name, NULL, NULL);
+           ct->c_storage = add (tmpfilenam, NULL);
 
-       /* Get the folder name */
-       if (cp[1])
-           folder = pluspath (cp);
-       else
-           folder = getfolder (1);
+           /* Get the folder name */
+           if (cp[1])
+               folder = pluspath (cp);
+           else
+               folder = getfolder (1);
 
-       /* Check if folder exists */
-       create_folder(m_mailpath(folder), 0, exit);
+           /* Check if folder exists */
+           create_folder(m_mailpath(folder), 0, exit);
 
-       /* Record the folder name */
-       ct->c_folder = add (folder, NULL);
+           /* Record the folder name */
+           ct->c_folder = add (folder, NULL);
 
-       if (cp[1])
-           free (folder);
+           if (cp[1])
+               free (folder);
 
-       goto got_filename;
-    }
+           goto got_filename;
+       }
 
-    /*
-     * Parse and expand the storage formatting string
-     * in `cp' into `buffer'.
-     */
-    parse_format_string (ct, cp, buffer, sizeof(buffer), dir);
+       /*
+        * Parse and expand the storage formatting string
+        * in `cp' into `buffer'.
+        */
+       parse_format_string (ct, cp, buffer, sizeof(buffer), dir);
 
-    /*
-     * If formatting begins with '|' or '!', then pass
-     * content to standard input of a command and return.
-     */
-    if (buffer[0] == '|' || buffer[0] == '!')
-       return show_content_aux (ct, 1, 0, buffer + 1, dir);
+       /*
+        * If formatting begins with '|' or '!', then pass
+        * content to standard input of a command and return.
+        */
+       if (buffer[0] == '|' || buffer[0] == '!')
+           return show_content_aux (ct, 1, 0, buffer + 1, dir);
 
-    /* record the filename */
-    if ((ct->c_storage = clobber_check (add (buffer, NULL))) == NULL) {
-      return NOTOK;
-    }
+        /* record the filename */
+       if ((ct->c_storage = clobber_check (add (buffer, NULL))) == NULL) {
+           return NOTOK;
+       }
+    } /* else output filename was explicitly specified, so use it */
 
 got_filename:
     /* flush the output stream */
@@ -1210,11 +1228,11 @@ static char *
 clobber_check (char *original_file) {
   /* clobber policy        return value
    * --------------        ------------
-   *   -always                 file
-   *   -auto           file-<digits>.extension
-   *   -suffix             file.<digits>
-   *   -ask          file, 0, or another filename/path
-   *   -never                   0
+   *   -always             original_file
+   *   -auto               original_file-<digits>.extension
+   *   -suffix             original_file.<digits>
+   *   -ask                original_file, 0, or another filename/path
+   *   -never              0
    */
 
   char *file;