From 8edc5aaf86f9f77124664f6801bc6c6cdf258173 Mon Sep 17 00:00:00 2001 From: markus schnalke Date: Thu, 29 Mar 2012 15:08:49 +0200 Subject: [PATCH 1/1] Trash folder replaces rmmproc. Rework of rmm(1) and refile(1). Removed several switches from refile and changed its behavior. (Although, rmm does not use backup prefixes anymore, other tools still do.) --- config/config.c | 11 ++-- docs/COMPLETION-BASH | 3 +- docs/COMPLETION-ZSH | 5 +- h/mh.h | 2 +- h/prototypes.h | 2 +- man/mh-profile.man5 | 25 +++++---- man/mhparam.man1 | 8 +-- man/refile.man1 | 92 ++------------------------------- man/rmm.man1 | 59 +++------------------ sbr/folder_delmsgs.c | 124 +++++++++----------------------------------- sbr/m_backup.c | 2 +- sbr/readconfig.c | 2 +- uip/mhparam.c | 2 +- uip/refile.c | 140 +++++++++++--------------------------------------- uip/rmm.c | 81 +++++++++++++++++++++++------ uip/whatnow.c | 6 +-- 16 files changed, 164 insertions(+), 400 deletions(-) diff --git a/config/config.c b/config/config.c index 82c66c3..31acdbb 100644 --- a/config/config.c +++ b/config/config.c @@ -71,6 +71,7 @@ char *mhlreply = "mhl.reply"; /* repl */ /* some default folder names */ char *defaultfolder = "+inbox"; char *draftfolder = "+drafts"; +char *trashfolder = "+trash"; char *inbox = "Inbox"; /* profile entry name to specify the default folder */ char *curfolder = "Current-Folder"; @@ -141,12 +142,6 @@ char *defaultpager = "more"; char *defaulteditor = "vi"; /* -** This program is called to remove a message by rmm or refile -nolink. -** It's usually empty, which means to rename the file to a backup name. -*/ -char *rmmproc = NULL; - -/* ** This program is called after comp, et. al., have built a draft */ char *whatnowproc = "whatnow"; @@ -168,7 +163,9 @@ char *mailspool = MAILSPOOL; /* ** The prefix that is prepended to the name of message files when they -** are "removed" by rmm. This should typically be `,' or `#'. +** are backup'd for some reason. send, for instance, does this. +** Note: rmm does NOT anymore use the backup prefix. +** It should typically be set to `,' or `#'. */ char *backup_prefix = ","; diff --git a/docs/COMPLETION-BASH b/docs/COMPLETION-BASH index 4938903..28aa29f 100644 --- a/docs/COMPLETION-BASH +++ b/docs/COMPLETION-BASH @@ -92,8 +92,7 @@ _nmh() -nocheckmime -version -help) ;; refile ) - options=(-link -nolink -preserve -nopreserve -unlink - -nounlink -src -file -rmmproc -normmproc -version -help) + options=(-link -nolink -src -file -version -help) ;; repl ) options=(-annotate -noannotate -group -nogroup -cc diff --git a/docs/COMPLETION-ZSH b/docs/COMPLETION-ZSH index cb21f3f..2b47557 100644 --- a/docs/COMPLETION-ZSH +++ b/docs/COMPLETION-ZSH @@ -144,9 +144,8 @@ compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \ mark compctl -K mhfseq -x 's[+][@]' \ - -K mhcomp -S / -q - 'c[-1,-file]' -f - 'c[-1,-rmmprov]' -c - \ - 's[-]' -k "(link nolink preserve nopreserve src file \ - rmmproc normmproc help)" -- refile + -K mhcomp -S / -q - 'c[-1,-file]' -f - \ + 's[-]' -k "(link nolink src file help)" -- refile compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - \ 's[-]' -k "(form \ diff --git a/h/mh.h b/h/mh.h index 8d698f4..ac8e665 100644 --- a/h/mh.h +++ b/h/mh.h @@ -307,7 +307,6 @@ extern char *psequence; extern char *rcvdistcomps; extern char *replcomps; extern char *replgroupcomps; -extern char *rmmproc; extern char *sendmail; extern char *seq_all; extern char *seq_beyond; @@ -318,6 +317,7 @@ extern char *seq_next; extern char *seq_prev; extern char *seq_unseen; extern char *seq_neg; +extern char *trashfolder; extern char *usequence; extern char *version_num; extern char *version_str; diff --git a/h/prototypes.h b/h/prototypes.h index 0e608d0..973da67 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -45,7 +45,7 @@ char *expandfol(char *); char *expanddir(char *); int ext_hook(char *, char *, char *); int folder_addmsg(struct msgs **, char *, int, int, int, int, char *); -int folder_delmsgs(struct msgs *, int, int); +int folder_delmsgs(struct msgs *, int); void folder_free(struct msgs *); struct msgs *folder_read(char *); struct msgs *folder_realloc(struct msgs *, int, int); diff --git a/man/mh-profile.man5 b/man/mh-profile.man5 index 5c051fb..ecc9ef4 100644 --- a/man/mh-profile.man5 +++ b/man/mh-profile.man5 @@ -178,7 +178,11 @@ to send mail. , .RS 5 The prefix that is prepended to the name of message files when they -are ``removed'' by rmm. This should typically be `,' or `#'. +are backup'd for some reason. +.BR send , +for instance, does this. +Note: rmm does NOT anymore use the backup prefix. +It should typically be set to `,' or `#'. (profile, default: `,') .RE .PP @@ -334,6 +338,15 @@ Changes the default draft folder. Read the man page for details. (profile, default: +drafts) .RE .PP +.BR Trash\-Folder : +trash +.RS 5 +Changes the default folder for removed messages. Read the +.BR rmm (1) +man page for details. +(profile, default: +trash) +.RE +.PP .BI digest\-issue\- list : 1 .RS 5 @@ -425,16 +438,6 @@ The absolute pathname of the message to list will be appended to the command line given. .RE .PP -.BR rmmproc : -none -.RS 5 -This is the program used by -.B rmm -and -.B refile -to delete a message from a folder. -.RE -.PP .BR whatnowproc : %bindir%/whatnow .RS 5 diff --git a/man/mhparam.man1 b/man/mhparam.man1 index b864caa..323bc24 100644 --- a/man/mhparam.man1 +++ b/man/mhparam.man1 @@ -61,13 +61,13 @@ vi % mhparam \-component Path Path: Mail -% mhparam AliasFile rmmproc +% mhparam AliasFile sendmail AliasFile: aliases -rmmproc: rmmproc +sendmail: /usr/sbin/sendmail -% mhparam \-nocomponent AliasFile rmmproc +% mhparam \-nocomponent AliasFile sendmail aliases -rmmproc +/usr/sbin/sendmail % mhparam path nonexistent context Path: Mail diff --git a/man/refile.man1 b/man/refile.man1 index 036baab..5e837f5 100644 --- a/man/refile.man1 +++ b/man/refile.man1 @@ -10,15 +10,10 @@ refile \- file message in other folders .B refile .RI [ msgs ] .RB [ \-link " | " \-nolink ] -.RB [ \-preserve " | " \-nopreserve ] -.RB [ \-unlink " | " \-nounlink ] .RB [ \-src .IR +folder ] .RB [ \-file .IR file ] -.RB [ \-rmmproc -.IR program ] -.RB [ \-normmproc ] .I +folder1 \&... .RB [ \-version ] @@ -98,67 +93,9 @@ rather than a whereas, .B \-nolink (the default) deletes the filed messages from the source folder. -.PP -Normally when a message is refiled, for each destination folder it -is assigned the number which is one above the current highest message -number in that folder. Use of the -.B \-preserv -switch will override -this message renaming, and try to preserve the number of the message. -If a conflict for a particular folder occurs when using the -.B \-preserve -switch, then -.B refile -will use the next available message number -which is above the message number you wish to preserve. -.PP -If -.B \-link -is not specified (or -.B \-nolink -is specified), the filed -messages will be removed from the source folder. The default is to -remove these messages by renaming them with a site-dependent prefix -(usually a comma). Such files will then need to be removed in some -manner after a certain amount of time. Many sites arrange for -.B cron -to remove these files once a day, so check with your -system administrator. -.PP -Alternately, if you wish for -.B refile -to really remove the files -representing these messages from the source folder, you can use the -.B -unlink -switch (not to be confused with the -.B \-link -switch). But -messages removed by this method cannot be later recovered. -.PP -If you prefer a more sophisticated method of `removing' the messages -from the source folder, you can define the -.B rmmproc -profile -component. For example, you can add a profile component such as -.PP -.RS 5 -rmmproc: /home/coleman/bin/rmm_msgs -.RE -.PP -then -.B refile -will instead call the named program or script to -handle the message files. -.PP -The user may specify -.B \-rmmproc -.I program -on the command line to -override this profile specification. The -.B \-normmproc -option forces -the message files to be deleted by renaming or unlinking them as -described above. +No backups are kept, because the contents don't vanish. +They are only moved to a new location. +To restore: refile the other way. .SH FILES .fc ^ ~ @@ -175,7 +112,6 @@ described above. ^Path:~^To determine the user's mail storage ^Current\-Folder:~^To find the default current folder ^Folder\-Protect:~^To set mode when creating a new folder -^rmmproc:~^Program to delete the message .fi .SH "SEE ALSO" @@ -186,8 +122,6 @@ folder(1), rmf(1), rmm(1) .RB ` "\-src\ +folder" "' defaults to the current folder" .RB ` msgs "' defaults to cur" .RB ` \-nolink ' -.RB ` \-nounlink ' -.RB ` \-nopreserve ' .fi .SH CONTEXT @@ -195,9 +129,9 @@ If .B \-src .I +folder is given, it will become the current folder. -If neither +If .B \-link -nor `all' is specified, the current message in the +is specified, the current message in the source folder will be set to the last message specified; otherwise, the current message won't be changed. .PP @@ -208,19 +142,3 @@ will also define those sequences for the destination folders. See .B mh\-sequence (7) for information concerning the previous sequence. - -.SH BUGS -Since -.B refile -uses your -.I rmmproc -to delete the message, -the -.I rmmproc -must -.B NOT -call -.B refile -without specifying -.BR \-normmproc , -or you will create an infinite loop. diff --git a/man/rmm.man1 b/man/rmm.man1 index 0cf138f..a271713 100644 --- a/man/rmm.man1 +++ b/man/rmm.man1 @@ -17,13 +17,9 @@ rmm \- remove messages .SH DESCRIPTION By default, .B rmm -will remove the specified messages by renaming -the message files with preceding commas. Such files will then need to -be removed in some manner after a certain amount of time. Many sites -arrange for -.B cron -to remove these files once a day, so check -with your system administrator. +will remove the specified messages by refiling them to the trash folder +`+trash'. The contents of this folder will then need to +be removed after a certain amount of time. .PP Alternately, if you wish for .B rmm @@ -33,37 +29,11 @@ representing these messages, you can use the switch. But messages removed by this method cannot be later recovered. .PP -If you prefer a more sophisticated method of `removing' messages, you -can define the -.I rmmproc -profile component. For example, you can -add a profile component such as -.PP -.RS 5 -rmmproc: /home/foouser/bin/rmm_msgs -.RE -.PP -then instead of simply renaming the message file, -.B rmm -will call -the named program or script to handle the files that represent the -messages to be deleted. -.PP -Some users of -.B csh -prefer the following: -.PP -.RS 5 -alias rmm 'refile +d' -.RE -.PP -where folder `+d' is a folder for deleted messages, and -.PP .RS 5 -alias mexp 'rm `mhpath +d all`' +rmm \-unlink +trash a .RE .PP -is used to \*(lqexpunge\*(rq deleted messages. +can be used to expunge deleted messages. .PP The current message is not changed by .BR rmm , @@ -86,7 +56,6 @@ advance to the next message in the folder as expected. .ta \w'ExtraBigProfileName 'u ^Path:~^To determine the user's mail storage ^Current\-Folder:~^To find the default current folder -^rmmproc:~^Program to delete the message .fi .SH "SEE ALSO" @@ -96,24 +65,8 @@ refile(1), rmf(1) .nf .RB ` +folder "' defaults to the current folder" .RB ` msgs "' defaults to cur" -.RB ` -nounlink ' +.RB ` \-nounlink ' .fi .SH CONTEXT If a folder is given, it will become the current folder. - -.SH BUGS -Since -.B refile -uses your -.I rmmproc -to delete the message, -the -.I rmmproc -must -.B NOT -call -.B refile -without specifying -.BR \-normmproc , -or you will create an infinte loop. diff --git a/sbr/folder_delmsgs.c b/sbr/folder_delmsgs.c index d6e63b6..17b99be 100644 --- a/sbr/folder_delmsgs.c +++ b/sbr/folder_delmsgs.c @@ -1,5 +1,5 @@ /* -** folder_delmsgs.c -- "remove" SELECTED messages from a folder +** folder_delmsgs.c -- remove (= unlink) SELECTED messages from a folder ** ** This code is Copyright (c) 2002, by the authors of nmh. See the ** COPYRIGHT file in the root directory of the nmh distribution for @@ -9,122 +9,48 @@ #include /* -** 1) If we are using an external rmmproc, then exec it. -** 2) Else if unlink_msgs is non-zero, then unlink the -** SELECTED messages. -** 3) Else rename SELECTED messages by prefixing name -** with backup_prefix. +** Unlink the SELECTED messages. ** ** If there is an error, return -1, else return 0. */ - int -folder_delmsgs(struct msgs *mp, int unlink_msgs, int nohook) +folder_delmsgs(struct msgs *mp, int hook) { - pid_t pid; - int msgnum, vecp, retval = 0; - char buf[100], *dp, **vec; + int msgnum, retval = 0; char msgpath[BUFSIZ]; - /* - ** If "rmmproc" is defined, exec it to remove messages. - */ - if (rmmproc) { - /* Unset the EXISTS flag for each message to be removed */ - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { - if (is_selected(mp, msgnum)) - unset_exists(mp, msgnum); - } - - /* Mark that the sequence information has changed */ - mp->msgflags |= SEQMOD; - - if (mp->numsel > MAXARGS - 2) - adios(NULL, "more than %d messages for %s exec", MAXARGS - 2, - rmmproc); - vec = (char **) calloc((size_t) (mp->numsel + 2), sizeof(*vec)); - if (vec == NULL) - adios(NULL, "unable to allocate exec vector"); - vecp = 1; - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { - if (is_selected(mp, msgnum) && - !(vec[vecp++] = strdup(m_name(msgnum)))) - adios(NULL, "strdup failed"); + for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { + if (!is_selected(mp, msgnum)) { + continue; } - vec[vecp] = NULL; - - fflush(stdout); - vec[0] = mhbasename(rmmproc); - switch (pid = fork()) { - case -1: - advise("fork", "unable to"); - return -1; + /* unselect message */ + unset_selected(mp, msgnum); + mp->numsel--; - case 0: - execvp(rmmproc, vec); - fprintf(stderr, "unable to exec "); - perror(rmmproc); - _exit(-1); + snprintf(msgpath, sizeof (msgpath), "%s/%d", + mp->foldpath, msgnum); - default: - return (pidwait(pid, -1)); + if (hook) { + /* Run the external hook on the message. */ + ext_hook("del-hook", msgpath, NULL); } - } - /* - ** Either unlink or rename the SELECTED messages - */ - for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { - if (is_selected(mp, msgnum)) { - /* unselect message */ - unset_selected(mp, msgnum); - mp->numsel--; - - /* - ** Run the external hook on the message if one - ** was specified in the context. All we have - ** is the message number; we have changed to - ** the directory containing the message. So, - ** we need to extract that directory to form the - ** complete path. Note that the caller knows the - ** directory, but has no way of passing that to us. - */ - - if (!nohook) { - snprintf(msgpath, sizeof (msgpath), "%s/%d", - mp->foldpath, msgnum); - ext_hook("del-hook", msgpath, NULL); - } - - dp = m_name(msgnum); - - if (unlink_msgs) { - /* just unlink the messages */ - if (unlink(dp) == -1) { - admonish(dp, "unable to unlink"); - retval = -1; - continue; - } - } else { - /* or rename messages with standard prefix */ - strncpy(buf, m_backup(dp), sizeof(buf)); - if (rename(dp, buf) == -1) { - admonish(buf, "unable to rename %s to", dp); - retval = -1; - continue; - } - } - - /* If removal was successful, decrement message count */ - unset_exists(mp, msgnum); - mp->nummsg--; + /* just unlink the messages */ + if (unlink(msgpath) == -1) { + admonish(msgpath, "unable to unlink"); + retval = -1; + continue; } + + /* If removal was successful, decrement message count */ + unset_exists(mp, msgnum); + mp->nummsg--; } /* Sanity check */ if (mp->numsel != 0) - adios(NULL, "oops, mp->numsel should be 0"); + adios(NULL, "oops, mp->numsel should be 0"); /* Mark that the sequence information has changed */ mp->msgflags |= SEQMOD; diff --git a/sbr/m_backup.c b/sbr/m_backup.c index 3749452..bdb0e86 100644 --- a/sbr/m_backup.c +++ b/sbr/m_backup.c @@ -19,7 +19,7 @@ m_backup(char *file) snprintf(buffer, sizeof(buffer), "%s%s", backup_prefix, cp); else snprintf(buffer, sizeof(buffer), "%.*s%s%s", (int)(cp - file), - file, backup_prefix, cp); + file, backup_prefix, cp); unlink(buffer); return buffer; diff --git a/sbr/readconfig.c b/sbr/readconfig.c index bcff1da..280d25b 100644 --- a/sbr/readconfig.c +++ b/sbr/readconfig.c @@ -24,8 +24,8 @@ static struct procstr procs[] = { { "altmsg-link", &altmsglink }, { "fileproc", &fileproc }, { "listproc", &listproc }, - { "rmmproc", &rmmproc }, { "sendmail", &sendmail }, + { "trash-folder", &trashfolder }, { "whatnowproc", &whatnowproc }, { NULL, NULL } }; diff --git a/uip/mhparam.c b/uip/mhparam.c index 20a95e7..7a1c512 100644 --- a/uip/mhparam.c +++ b/uip/mhparam.c @@ -43,7 +43,6 @@ static struct proc procs [] = { { "mimetypequeryproc", &mimetypequeryproc }, { "msgprot", &msgprot }, { "pager", &defaultpager }, - { "rmmproc", &rmmproc }, { "sendmail", &sendmail }, { "version", &version_num }, { "whatnowproc", &whatnowproc }, @@ -51,6 +50,7 @@ static struct proc procs [] = { { "backup-prefix", &backup_prefix }, { "altmsg-link", &altmsglink }, { "draft-folder", &draftfolder }, + { "trash-folder", &trashfolder }, { NULL, NULL }, }; diff --git a/uip/refile.c b/uip/refile.c index e699a14..318d555 100644 --- a/uip/refile.c +++ b/uip/refile.c @@ -17,25 +17,13 @@ static struct swit switches[] = { { "link", 0 }, #define NLINKSW 1 { "nolink", 0 }, -#define PRESSW 2 - { "preserve", 0 }, -#define NPRESSW 3 - { "nopreserve", 0 }, -#define UNLINKSW 4 - { "unlink", 0 }, -#define NUNLINKSW 5 - { "nounlink", 0 }, -#define SRCSW 6 +#define SRCSW 2 { "src +folder", 0 }, -#define FILESW 7 +#define FILESW 3 { "file file", 0 }, -#define RPROCSW 8 - { "rmmproc program", 0 }, -#define NRPRCSW 9 - { "normmproc", 0 }, -#define VERSIONSW 10 +#define VERSIONSW 4 { "version", 0 }, -#define HELPSW 11 +#define HELPSW 5 { "help", 0 }, { NULL, 0 } }; @@ -52,20 +40,19 @@ struct st_fold { */ static void opnfolds(struct st_fold *, int); static void clsfolds(struct st_fold *, int); -static void remove_files(int, char **); -static int m_file(char *, struct st_fold *, int, int, int); +static int m_file(char *, struct st_fold *, int, int); int main(int argc, char **argv) { - int linkf = 0, preserve = 0, filep = 0; - int foldp = 0, unlink_msgs = 0; + int linkf = 0, filep = 0; + int foldp = 0; int i, msgnum; char *cp, *folder = NULL, buf[BUFSIZ]; char **argp, **arguments; - char *filevec[NFOLDERS + 2]; - char **files = &filevec[1]; /* leave room for remove_files:vec[0] */ + char *filevec[NFOLDERS + 1]; + char **files = filevec; struct st_fold folders[NFOLDERS + 1]; struct msgs_array msgs = { 0, 0, NULL }; struct msgs *mp; @@ -75,7 +62,6 @@ main(int argc, char **argv) #endif invo_name = mhbasename(argv[0]); - /* read user profile/context */ context_read(); arguments = getarguments(invo_name, argc, argv, 1); @@ -108,20 +94,6 @@ main(int argc, char **argv) linkf = 0; continue; - case PRESSW: - preserve++; - continue; - case NPRESSW: - preserve = 0; - continue; - - case UNLINKSW: - unlink_msgs++; - continue; - case NUNLINKSW: - unlink_msgs = 0; - continue; - case SRCSW: if (folder) adios(NULL, "only one source folder at a time!"); @@ -139,15 +111,6 @@ main(int argc, char **argv) argp[-2]); files[filep++] = getcpy(expanddir(cp)); continue; - - case RPROCSW: - if (!(rmmproc = *argp++) || *rmmproc == '-') - adios(NULL, "missing argument to %s", - argp[-2]); - continue; - case NRPRCSW: - rmmproc = NULL; - continue; } } if (*cp == '+' || *cp == '@') { @@ -175,11 +138,19 @@ main(int argc, char **argv) adios(NULL, "use -file or some messages, not both"); opnfolds(folders, foldp); for (i = 0; i < filep; i++) - if (m_file(files[i], folders, foldp, preserve, 0)) + if (m_file(files[i], folders, foldp, 0)) done(1); - /* If -nolink, then "remove" files */ - if (!linkf) - remove_files(filep, filevec); + /* If -nolink, then unlink files */ + if (!linkf) { + int i; + char **files = filevec; + + /* just unlink the files */ + for (i = 0; i < filep; i++) { + if (unlink(files[i]) == NOTOK) + admonish(files[i], "unable to unlink"); + } + } done(0); } @@ -218,44 +189,32 @@ main(int argc, char **argv) for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { if (is_selected(mp, msgnum)) { cp = getcpy(m_name(msgnum)); - if (m_file(cp, folders, foldp, preserve, !linkf)) + if (m_file(cp, folders, foldp, !linkf)) done(1); free(cp); } } /* - ** This is a hack. If we are using an external rmmproc, - ** then save the current folder to the context file, - ** so the external rmmproc will remove files from the correct - ** directory. This should be moved to folder_delmsgs(). - */ - if (rmmproc) { - context_replace(curfolder, folder); - context_save(); - fflush(stdout); - } - - /* - ** If -nolink, then "remove" messages from source folder. + ** If -nolink, then remove (= unlink) messages from source folder. ** ** Note that folder_delmsgs does not call the delete hook ** because the message has already been handled above. */ if (!linkf) { - folder_delmsgs(mp, unlink_msgs, 1); + folder_delmsgs(mp, 0); } clsfolds(folders, foldp); - if (mp->hghsel != mp->curmsg && - (mp->numsel != mp->nummsg || linkf)) + if (linkf) { seq_setcur(mp, mp->hghsel); + } seq_save(mp); /* synchronize message sequences */ - context_replace(curfolder, folder); /* update current folder */ - context_save(); /* save the context file */ - folder_free(mp); /* free folder structure */ + context_replace(curfolder, folder); + context_save(); + folder_free(mp); done(0); return 1; } @@ -265,7 +224,6 @@ main(int argc, char **argv) ** Read all the destination folders and ** create folder structures for all of them. */ - static void opnfolds(struct st_fold *folders, int nfolders) { @@ -296,7 +254,6 @@ opnfolds(struct st_fold *folders, int nfolders) ** Set the Previous-Sequence and then sychronize the ** sequence file, for each destination folder. */ - static void clsfolds(struct st_fold *folders, int nfolders) { @@ -312,53 +269,18 @@ clsfolds(struct st_fold *folders, int nfolders) /* -** If you have a "rmmproc" defined, we called that -** to remove all the specified files. If "rmmproc" -** is not defined, then just unlink the files. -*/ - -static void -remove_files(int filep, char **files) -{ - int i; - char **vec; - - /* If rmmproc is defined, we use that */ - if (rmmproc) { - vec = files++; /* vec[0] = filevec[0] */ - files[filep] = NULL; /* NULL terminate list */ - - fflush(stdout); - vec[0] = mhbasename(rmmproc); - execvp(rmmproc, vec); - adios(rmmproc, "unable to exec"); - } - - /* Else just unlink the files */ - files++; /* advance past filevec[0] */ - for (i = 0; i < filep; i++) { - if (unlink(files[i]) == NOTOK) - admonish(files[i], "unable to unlink"); - } -} - - -/* ** Link (or copy) the message into each of ** the destination folders. */ - static int -m_file(char *msgfile, struct st_fold *folders, int nfolders, int preserve, - int refile) +m_file(char *msgfile, struct st_fold *folders, int nfolders, int refile) { int msgnum; struct st_fold *fp, *ep; for (fp = folders, ep = folders + nfolders; fp < ep; fp++) { if ((msgnum = folder_addmsg(&fp->f_mp, msgfile, 1, 0, - preserve, nfolders == 1 && refile, maildir)) - == -1) + 0, nfolders == 1 && refile, maildir)) == -1) return 1; } return 0; diff --git a/uip/rmm.c b/uip/rmm.c index 35983bd..ecc9b9b 100644 --- a/uip/rmm.c +++ b/uip/rmm.c @@ -25,19 +25,20 @@ static struct swit switches[] = { int main(int argc, char **argv) { - int msgnum, unlink_msgs = 0; - char *cp, *maildir, *folder = NULL; + int msgnum, unlink_msgs = 0, vecp = 0; + char *cp, *maildir, *folder = NULL, **vec; char buf[BUFSIZ], **argp; char **arguments; struct msgs_array msgs = { 0, 0, NULL }; struct msgs *mp; + pid_t pid; + #ifdef LOCALE setlocale(LC_ALL, ""); #endif invo_name = mhbasename(argv[0]); - /* read user profile/context */ context_read(); arguments = getarguments(invo_name, argc, argv, 1); @@ -101,26 +102,72 @@ main(int argc, char **argv) done(1); seq_setprev(mp); /* set the previous-sequence */ + + if (unlink_msgs) { + /* "remove" the SELECTED messages */ + folder_delmsgs(mp, 1); + + seq_save(mp); + context_replace(curfolder, folder); + context_save(); + folder_free(mp); + done(0); + return 1; + } + /* - ** This is hackish. If we are using a external rmmproc, + ** This is hackish. If we don't unlink, but refile, ** then we need to update the current folder in the - ** context so the external rmmproc will remove files - ** from the correct directory. This should be moved to - ** folder_delmsgs(). + ** context so the external program will refile files + ** from the correct directory. */ - if (rmmproc) { - context_replace(curfolder, folder); - context_save(); - fflush(stdout); + context_replace(curfolder, folder); + context_save(); + fflush(stdout); + + /* remove by refiling. */ + /* Unset the EXISTS flag for each message to be removed */ + for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { + if (is_selected(mp, msgnum)) + unset_exists(mp, msgnum); + } + + /* Mark that the sequence information has changed */ + mp->msgflags |= SEQMOD; + + if (mp->numsel+4 > MAXARGS) + adios(NULL, "more than %d messages for refile exec", + MAXARGS - 4); + vec = (char **)mh_xmalloc((size_t)(mp->numsel + 4) * sizeof(*vec)); + vec[vecp++] = "refile"; + vec[vecp++] = "-nolink"; + vec[vecp++] = concat("+", trashfolder, NULL); + for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { + if (!is_selected(mp, msgnum)) { + continue; + } + if (!(vec[vecp++] = strdup(m_name(msgnum)))) { + adios(NULL, "strdup failed"); + } } + vec[vecp] = NULL; + + fflush(stdout); + switch (pid = fork()) { + case -1: + adios("fork", "unable to"); - /* "remove" the SELECTED messages */ - folder_delmsgs(mp, unlink_msgs, 0); + case 0: + execvp(*vec, vec); + fprintf(stderr, "unable to exec "); + perror(*vec); + _exit(-1); + + default: + pidwait(pid, -1); + } - seq_save(mp); /* synchronize message sequences */ - context_replace(curfolder, folder); /* update current folder */ - context_save(); /* save the context file */ - folder_free(mp); /* free folder structure */ + folder_free(mp); done(0); return 1; } diff --git a/uip/whatnow.c b/uip/whatnow.c index d0b0f93..6e58052 100644 --- a/uip/whatnow.c +++ b/uip/whatnow.c @@ -671,9 +671,9 @@ editfile(char **ed, char **arg, char *file, int use, struct msgs *mp, default: if ((status = pidwait(pid, NOTOK))) { - if (((status & 0xff00) != 0xff00) - && (!reedit || (status & 0x00ff))) { - if (!use && (status & 0xff00) && (rename(file, cp = m_backup (file)) != NOTOK)) { + if (((status & 0xff00) != 0xff00) && + (!reedit || (status & 0x00ff))) { + if (!use && (status & 0xff00) && (rename(file, cp = m_backup(file)) != NOTOK)) { advise(NULL, "problems with edit--draft left in %s", cp); } else { advise(NULL, "problems with edit--%s preserved", file); -- 1.7.10.4