From: David Levine Date: Sun, 28 Apr 2013 16:29:47 +0000 (-0500) Subject: Added -outfile switch to mhstore(1). X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/4ea717b986c4b0ce9ccd01687c7b50bd2ab227ca?hp=5322d1ddd3b63092a1566e18fddd13f619bd1cba Added -outfile switch to mhstore(1). --- diff --git a/docs/pending-release-notes b/docs/pending-release-notes index c71cf1ee..64b1d71c 100644 --- a/docs/pending-release-notes +++ b/docs/pending-release-notes @@ -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. diff --git a/man/mhstore.man b/man/mhstore.man index 691abac6..d39994ef 100644 --- a/man/mhstore.man +++ b/man/mhstore.man @@ -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 diff --git a/test/mhstore/test-mhstore b/test/mhstore/test-mhstore index d509abe5..b332cd92 100755 --- a/test/mhstore/test-mhstore +++ b/test/mhstore/test-mhstore @@ -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" diff --git a/uip/mhstore.c b/uip/mhstore.c index ff18533d..79f335e5 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -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); + } + } } } } diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index 4d26b573..fab16800 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -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-.extension - * -suffix file. - * -ask file, 0, or another filename/path - * -never 0 + * -always original_file + * -auto original_file-.extension + * -suffix original_file. + * -ask original_file, 0, or another filename/path + * -never 0 */ char *file;