From 41b6eadbcecf63c9a66aa5e582011987494abefb Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Thu, 12 Apr 2012 17:30:56 +0200 Subject: [PATCH] mhstore -auto: Never store into subdirs, but use basename of filename. 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 | 56 ++++++++++++++++++++++++++++-------------------------- uip/mhstore.c | 29 ++++++++++++++++------------ 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/man/mhstore.man1 b/man/mhstore.man1 index faf8ea5..15f4939 100644 --- a/man/mhstore.man1 +++ b/man/mhstore.man1 @@ -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. diff --git a/uip/mhstore.c b/uip/mhstore.c index 6f6746d..50c911c 100644 --- a/uip/mhstore.c +++ b/uip/mhstore.c @@ -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) -- 1.7.10.4