mhstore -auto: Never store into subdirs, but use basename of filename.
authormarkus schnalke <meillo@marmaro.de>
Thu, 12 Apr 2012 15:30:56 +0000 (17:30 +0200)
committermarkus schnalke <meillo@marmaro.de>
Thu, 12 Apr 2012 15:30:56 +0000 (17:30 +0200)
Now, the only remaining problem with -auto is overwriting of existing files.
But actually that's no problem of -auto, because the behavior is the same
with -noauto.

man/mhstore.man1
uip/mhstore.c

index faf8ea5..15f4939 100644 (file)
@@ -124,7 +124,22 @@ The
 .B mhstore
 will store the contents of the named messages in
 \*(lqnative\*(rq (decoded) format.  Two things must be determined:
-the directory to store the content, and the filenames.  Files are
+the directory to store the content, and the filenames.
+.PP
+By default (or if the
+.B \-auto
+switch is given),
+.B mhstore
+uses filename information, contained in the message, if available.
+(This information should be specified
+as the attribute \*(lqname=filename\*(rq in the \*(lqContent-Type\*(rq header
+for the content you are storing.)
+Only the basename of this filename is considered.
+If it begins with the character '.', '|', or '!',
+or if it contains the character '%', automatic naming won't happen for
+security reasons. (See below for the fall-back.)
+.PP
+Files are
 written in the directory given by the \*(lqnmh-storage\*(rq profile
 entry, e.g.,
 .PP
@@ -132,30 +147,17 @@ entry, e.g.,
 nmh-storage: /tmp
 .RE
 .PP
+(Note that \*(lqnmh-storage\*(rq is relative to the folder that contains
+the message.)
 If this entry isn't present,
 the current working directory is used.
-.PP
-By default (or if the
-.B \-auto
-switch is given), then
-.B mhstore
-will check if
-the message contains information indicating the filename that should
-be used to store the content.  This information should be specified
-as the attribute \*(lqname=filename\*(rq in the \*(lqContent-Type\*(rq header
-for the content you are storing.  For security reasons, this filename
-will be ignored if it begins with the character '/', '.', '|', or '!',
-or if it contains the character '%'. Now that tar files are not extracted
-automatically anymore, having
-.B \-auto
-as the default is quite safe.
-Attachments are only stored below the current (or the storage)
-directory. In the worst case, existing files there will be overwritten.
+Attachments will get stored in either the `nmh-storage' or the current working
+directory \(en in no case elsewhere.
+Existing files get silently overwritten.
 .PP
 If the
-.B \-auto
-switch is not given (or is being ignored for security
-reasons) then
+.B \-noauto
+switch is given (or a filename is being ignored for security reasons) then
 .B mhstore
 will look in the user's profile for a
 \*(lqformatting string\*(rq to determine how the different contents
@@ -183,7 +185,7 @@ content is stored in the named folder.  A formatting string consisting
 solely of a \*(lq+\*(rq character is interpreted to be the current
 folder.
 .PP
-If the formatting string consists solely of a \*(lq-\*(rq character,
+If the formatting string consists solely of a \*(lq\-\*(rq character,
 then the content is sent to the standard output.
 .PP
 If the formatting string starts with a '|', then the display string
@@ -199,11 +201,9 @@ escapes (given below) in the display string will be expanded.
 Otherwise the formatting string will represent a pathname in which
 to store the content.  If the formatting string starts with a '/',
 then the content will be stored in the full path given, else the
-file name will be relative to the value of \*(lqnmh-storage\*(rq or
-the current working directory.  Any escapes (given below) will be
-expanded, except for the a-escape.  Note that if \*(lqnmh-storage\*(rq
-is not an absolute path, it will be relative to the folder that
-contains the message(s).
+file name will be relative to either the value of \*(lqnmh-storage\*(rq,
+if set, or the current working directory.
+Existing files get silently overwritten.
 .PP
 A command or pathname formatting string may contain the following
 escapes.  If the content isn't part of a multipart (of any subtype
@@ -392,3 +392,5 @@ message selected will become the current message.
 
 .SH BUGS
 Partial messages contained within a multipart content are not reassembled.
+.PP
+Existing files get silently overwritten.
index 6f6746d..50c911c 100644 (file)
@@ -470,7 +470,7 @@ store_switch(CT ct)
 static int
 store_generic(CT ct)
 {
-       char **ap, **ep, *cp;
+       char **ap, **vp, *cp;
        CI ci = &ct->c_ctinfo;
 
        /*
@@ -483,17 +483,20 @@ store_generic(CT ct)
        if (autosw && ct->c_type != CT_MESSAGE && !ct->c_storeproc) {
                /*
                ** Check the attribute/value pairs, for the attribute "name".
-               ** If found, do a few sanity checks and copy the value into
-               ** the storeproc.
+               ** If found, take the basename, do a few sanity checks and
+               ** copy the value into c_storeproc.
                */
-               for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
-                       if (mh_strcasecmp(*ap, "name")==0 &&
-                                       *(cp = *ep) != '/' && *cp != '.' &&
-                                       *cp != '|' && *cp != '!' &&
+               for (ap = ci->ci_attrs, vp = ci->ci_values; *ap; ap++,vp++) {
+                       if (mh_strcasecmp(*ap, "name")!=0) {
+                               continue;
+                       }
+                       cp = mhbasename(*vp);
+                       if (*cp && *cp!='.' && *cp!='|' && *cp!='!' &&
                                        !strchr(cp, '%')) {
+                               /* filename looks good: use it */
                                ct->c_storeproc = getcpy(cp);
-                               break;
                        }
+                       break;
                }
        }
 
@@ -650,8 +653,10 @@ store_external(CT ct)
        if (autosw) {
                char *cp;
 
-               if ((cp = e->eb_name) && *cp != '/' && *cp != '.' &&
-                               *cp != '|' && *cp != '!' && !strchr(cp, '%')) {
+               cp = mhbasename(e->eb_name);
+               if (*cp && *cp!='.' && *cp!='|' && *cp!='!' &&
+                               !strchr(cp, '%')) {
+                       /* filename looks good: use it */
                        if (!ct->c_storeproc)
                                ct->c_storeproc = getcpy(cp);
                        if (!p->c_storeproc)
@@ -900,8 +905,8 @@ output_content_file(CT ct, int appending)
        FILE *fp;
 
        /*
-       ** If the pathname is absolute, make sure
-       ** all the relevant directories exist.
+       ** If the pathname contains directories, make sure
+       ** all of them exist.
        */
        if (strchr(ct->c_storage, '/') && make_intermediates(ct->c_storage)
                        == NOTOK)