From: Ken Hornstein Date: Thu, 21 Mar 2013 21:14:30 +0000 (-0400) Subject: Merge branch 'newlock' X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/17932f7aea1c21cf17738f47996345d9d0a6ce51?ds=inline;hp=-c Merge branch 'newlock' --- 17932f7aea1c21cf17738f47996345d9d0a6ce51 diff --combined Makefile.am index a18a7c63,074adb26..1e64f159 --- a/Makefile.am +++ b/Makefile.am @@@ -37,6 -37,7 +37,7 @@@ TESTS_ENVIRONMENT = MH_OBJ_DIR="@abs_bu MH_TEST_DIR="@abs_builddir@/test/testdir" \ auxexecdir="$(auxexecdir)" bindir="$(bindir)" \ mandir="$(mandir)" sysconfdir="$(sysconfdir)" \ + supported_locks="$(supported_locks)" \ MULTIBYTE_ENABLED=$(MULTIBYTE_ENABLED) \ ICONV_ENABLED=$(ICONV_ENABLED) \ $(TESTS_SHELL) ## Keep at end of TESTS_ENVIRONMENT. @@@ -58,9 -59,10 +59,11 @@@ TESTS = test/ali/test-ali test/anno/tes test/inc/test-deb359167 test/inc/test-eom-align \ test/inc/test-inc-scanout test/inc/test-msgchk \ test/inc/test-pop \ - test/install-mh/test-install-mh test/manpages/test-manpages \ + test/install-mh/test-install-mh \ + test/locking/test-datalocking test/locking/test-spoollocking \ + test/manpages/test-manpages \ test/mhbuild/test-forw test/mhbuild/test-utf8-body \ + test/mhfixmsg/test-mhfixmsg \ test/mhlist/test-mhlist test/mhmail/test-mhmail \ test/mhparam/test-mhparam test/mhpath/test-mhpath \ test/mhshow/test-cte-binary test/mhshow/test-qp \ @@@ -127,11 -129,11 +130,11 @@@ BUILT_SOURCES = sbr/sigmsg.h sbr/ctype- ## bin_PROGRAMS = uip/ali uip/anno uip/burst uip/comp uip/dist uip/flist \ uip/fmttest uip/folder uip/forw uip/inc uip/install-mh \ - uip/mark uip/mhbuild uip/mhlist uip/mhn uip/mhparam \ - uip/mhpath uip/mhshow uip/mhstore uip/msgchk uip/msh uip/new \ - uip/packf uip/pick uip/prompter uip/refile uip/repl uip/rmf \ - uip/rmm uip/scan uip/send uip/show uip/sortm uip/whatnow \ - uip/whom + uip/mark uip/mhbuild uip/mhfixmsg uip/mhlist uip/mhn \ + uip/mhparam uip/mhpath uip/mhshow uip/mhstore uip/msgchk \ + uip/msh uip/new uip/packf uip/pick uip/prompter uip/refile \ + uip/repl uip/rmf uip/rmm uip/scan uip/send uip/show uip/sortm \ + uip/whatnow uip/whom bin_SCRIPTS = uip/mhmail etc/sendfiles @@@ -213,9 -215,9 +216,9 @@@ man_MANS = man/ali.1 man/anno.1 man/ap. man/forw.1 man/fprev.1 man/inc.1 man/install-mh.1 man/mark.1 \ man/mh-alias.5 man/mh-chart.7 man/mh-draft.5 man/mh-folders.5 \ man/mh-format.5 man/mh-mail.5 man/mh-profile.5 man/mh_profile.5 \ - man/mh-sequence.5 man/mh-tailor.5 man/mhbuild.1 man/mhl.1 \ - man/mhlist.1 man/mhmail.1 man/mhn.1 man/mhparam.1 man/mhpath.1 \ - man/mhshow.1 man/mhstore.1 man/msgchk.1 man/msh.1 \ + man/mh-sequence.5 man/mh-tailor.5 man/mhbuild.1 man/mhfixmsg.1 \ + man/mhl.1 man/mhlist.1 man/mhmail.1 man/mhn.1 man/mhparam.1 \ + man/mhpath.1 man/mhshow.1 man/mhstore.1 man/msgchk.1 man/msh.1 \ man/mts.conf.5 man/new.1 man/next.1 man/nmh.7 man/packf.1 \ man/pick.1 man/post.8 man/prev.1 man/prompter.1 man/rcvdist.1 \ man/rcvpack.1 man/rcvstore.1 man/rcvtty.1 man/refile.1 \ @@@ -234,10 -236,10 +237,10 @@@ man_SRCS = man/ali.man man/anno.man man man/mh-chart-gen.sh man/mh-draft.man man/mh-folders.man \ man/mh-format.man man/mh-mail.man man/mh-profile.man \ man/mh_profile.man man/mh-sequence.man man/mh-tailor.man \ - man/mhbuild.man man/mhl.man man/mhlist.man man/mhmail.man \ - man/mhn.man man/mhparam.man man/mhpath.man man/mhshow.man \ - man/mhstore.man man/msgchk.man man/msh.man man/mts.conf.man \ - man/new.man man/next.man man/nmh.man \ + man/mhbuild.man man/mhfixmsg.man man/mhl.man man/mhlist.man \ + man/mhmail.man man/mhn.man man/mhparam.man man/mhpath.man \ + man/mhshow.man man/mhstore.man man/msgchk.man man/msh.man \ + man/mts.conf.man man/new.man man/next.man man/nmh.man \ man/packf.man man/pick.man man/post.man man/prev.man \ man/prompter.man man/rcvdist.man man/rcvpack.man \ man/rcvstore.man man/rcvtty.man man/refile.man man/repl.man \ @@@ -301,12 -303,6 +304,12 @@@ uip_mhbuild_SOURCES = uip/mhbuild.c uip uip/mhfree.c uip/mhparse.c uip/termsbr.c uip/md5.c uip_mhbuild_LDADD = $(LDADD) $(TERMLIB) +uip_mhfixmsg_SOURCES = uip/mhfixmsg.c uip/mhparse.c uip/mhcachesbr.c \ + uip/mhoutsbr.c uip/mhmisc.c uip/mhfree.c \ + uip/mhshowsbr.c uip/mhlistsbr.c \ + uip/termsbr.c uip/md5.c +uip_mhfixmsg_LDADD = $(LDADD) $(ICONVLIB) $(TERMLIB) + uip_mhlist_SOURCES = uip/mhlist.c uip/mhparse.c uip/mhcachesbr.c \ uip/mhlistsbr.c uip/mhmisc.c uip/mhfree.c uip/termsbr.c \ uip/md5.c @@@ -455,6 -451,8 +458,8 @@@ etc/mts.conf: $(srcdir)/etc/mts.conf.i $(SED) -e 's,%mts%,$(MTS),' \ -e 's,%mailspool%,$(mailspool),' \ -e 's,%smtpservers%,$(smtpservers),' \ + -e 's,%default_locking%,$(default_locking),' \ + -e 's,%supported_locks%,$(supported_locks),' \ < $(srcdir)/etc/mts.conf.in > $@ etc/mhn.defaults: $(srcdir)/etc/mhn.defaults.sh $(MHNSEARCHPROG) @@@ -545,13 -543,6 +550,13 @@@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr sbr/m_mktemp.c sbr/getansreadline.c config/config.c \ config/version.c +## +## Because these files use the definitions in the libmh rule below, +## they need to be rebuilt if the Makefile changes. +## + +config/sbr_libmh_a-config.$(OBJEXT) sbr/sbr_libmh_a-mts.$(OBJEXT): Makefile + sbr_libmh_a_CPPFLAGS = -I./sbr -DNMHETCDIR='"$(sysconfdir)"' \ -DMAILSPOOL='"$(mailspool)"' \ -DSENDMAILPATH='"$(sendmailpath)"' -DNMHBINDIR='"$(bindir)"' \ @@@ -579,6 -570,8 +584,8 @@@ man/man.sed: Makefil @echo 's,%mandir%,$(mandir),g' >> $@ @echo 's,%mailspool%,$(mailspool),g' >> $@ @echo 's,%sendmailpath%,$(sendmailpath),g' >> $@ + @echo 's,%default_locking%,$(default_locking),g' >> $@ + @echo 's,%supported_locks%,$(supported_locks),g' >> $@ @echo 's,%manext1%,$(manext1),g' >> $@ @echo 's,%manext5%,$(manext5),g' >> $@ @echo 's,%manext7%,$(manext7),g' >> $@ diff --combined configure.ac index 46c831b5,bfa3c518..de7f93f1 --- a/configure.ac +++ b/configure.ac @@@ -8,7 -8,7 +8,7 @@@ AC_PREREQ([2.68] AC_INIT([nmh], m4_normalize(m4_include([VERSION])), [nmh-workers@nongnu.org]) AC_CONFIG_SRCDIR([h/nmh.h]) AC_CONFIG_HEADER([config.h]) -AM_INIT_AUTOMAKE([-Wall color-tests foreign serial-tests subdir-objects 1.12]) +AM_INIT_AUTOMAKE([-Wall foreign serial-tests subdir-objects 1.12]) AC_CANONICAL_HOST @@@ -62,43 -62,6 +62,6 @@@ AS_IF([test x"$with_hash_backup" != x - AC_DEFINE_UNQUOTED([BACKUP_PREFIX], "$backup_prefix", [The prefix that is prepended to the name of message files when they are "removed" by rmm. This should typically be `,' or `#'.])dnl - dnl What method of locking to use? - AS_CASE(["$host_os"], - [aix*|cygwin*|linux*], - [default_locktype="fcntl"; default_locking=FCNTL_LOCKING], - [freebsd*|openbsd*|darwin*], [default_locktype="flock"; default_locking=FLOCK_LOCKING], - [default_locktype="dot"; default_locking=DOT_LOCKING]) - - AC_ARG_WITH([locking], - AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@], - [specify the file locking method])) - - AS_IF([test x"$with_locking" = x"dot"], - [LOCKTYPE="dot" - AC_DEFINE([DOT_LOCKING], [1], [Define to use dot based file locking.])], - [test x"$with_locking" = x"flock"], - [LOCKTYPE="flock" - AC_DEFINE([FLOCK_LOCKING], [1], [Define to use flock() based locking.])], - [test x"$with_locking" = x"lockf"], - [LOCKTYPE="lockf" - AC_DEFINE([LOCKF_LOCKING], [1], [Define to use lockf() based locking.])], - [test x"$with_locking" = x"fcntl"], - [LOCKTYPE="fcntl" - AC_DEFINE([FCNTL_LOCKING], [1], [Define to use fnctl() based locking.])], - [LOCKTYPE="$default_locktype" - AC_DEFINE_UNQUOTED([$default_locking], [1])]) - - dnl Should we use a locking directory? - AC_ARG_ENABLE([lockdir], - [AS_HELP_STRING([--enable-lockdir=dir], [Store dot-lock files in "dir"])], [ - AS_IF([test "x$enableval" = xyes],[ - AC_MSG_ERROR([--enable-lockdir requires an argument])]) - AS_IF([test "x$LOCKTYPE" != xdot],[ - AC_MSG_ERROR([Can only use --enable-lockdir with dot locking])]) - AC_DEFINE_UNQUOTED([LOCKDIR], ["$enableval"], - [Directory to store dot-locking lock files]) - ]) - dnl What method of posting should post use? AC_ARG_WITH([mts], AS_HELP_STRING([--with-mts=@<:@smtp|sendmail/smtp|sendmail/pipe@:>@], @@@ -409,6 -372,9 +372,9 @@@ NMH_CHECK_NETLIB dnl Check for readline support NMH_READLINE + dnl Check the locking functions supported and what we should use by default + NMH_LOCKING + dnl Check for iconv NMH_CHECK_ICONV @@@ -680,9 -646,8 +646,8 @@@ man page install path : ${nmhman RPM build root : ${nmhrpm} backup prefix : ${backup_prefix} transport system : ${MTS} - file locking type : ${LOCKTYPE} + spool default locking type : ${with_locking} default smtp servers : ${smtpservers} - default editor : ${editorpath} SASL support : ${sasl_support} TLS support : ${tls_support} ])])dnl diff --combined docs/pending-release-notes index 899318ef,3ff8fbd9..e275dfa6 --- a/docs/pending-release-notes +++ b/docs/pending-release-notes @@@ -44,12 -44,7 +44,13 @@@ NEW FEATURE - A new program, fmttest(1) is included to help debug format files - mhshow/mhstore now have support for RFC-2017 (access-type=url) for external message bodies. +- Added -retainsequences switch to refile(1). +- A new program, mhfixmsg(1), is included to rewrite MIME messages with + various transformations. +- Added -[no]rmmproc switches to rmm(1). +- Added support for Content-Disposition header (RFC 2183) to mhstore(1) + and mhn(1) when used with -auto. + - All nmh commands now support transactional locking for sequence files. ---------------------------- OBSOLETE/DEPRECATED FEATURES diff --combined man/mh-profile.man index 25f57145,75bea09d..a85522b0 --- a/man/mh-profile.man +++ b/man/mh-profile.man @@@ -1,4 -1,4 +1,4 @@@ -.TH MH-PROFILE %manext5% "November 6, 2012" "%nmhversion%" +.TH MH-PROFILE %manext5% "March 18, 2013" "%nmhversion%" .\" .\" %nmhwarning% .\" @@@ -189,6 -189,28 +189,28 @@@ for an explanation of the octal number (profile, default: 700) .RE .PP + .BR datalocking : + fcntl + .RS 5 + The locking algorithm used to lock changes to any + .B nmh + data files, such as sequences or the context. The locking algorithm is + any one of the following entries: + .PP + .RS 5 + .nf + %supported_locks% + .fi + .RE + .PP + Available locking algorithms can vary depending on what is supported by + the operating system. Note: currently transactional locking is only + supported on public sequences; see + .IR mh\-sequence (5) + for more information. + (profile, default: fcntl) + .RE + .PP .IR program : .I default switches .RS 5 @@@ -535,10 -557,9 +557,10 @@@ to do address verification none .RS 5 This is the program used by -.B rmm +.BR rmm , +.BR refile , and -.B refile +.B mhfixmsg to delete a message from a folder. .RE .PP diff --combined uip/mhbuildsbr.c index 121978d7,459a2559..5d3679f6 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@@ -347,6 -347,12 +347,6 @@@ finish_field static int init_decoded_content (CT ct) { - CE ce; - - if ((ce = (CE) calloc (1, sizeof(*ce))) == NULL) - adios (NULL, "out of memory"); - - ct->c_cefile = ce; ct->c_ceopenfnx = open7Bit; /* since unencoded */ ct->c_ceclosefnx = close_encoding; ct->c_cesizefnx = NULL; /* since unencoded */ @@@ -424,7 -430,7 +424,7 @@@ user_content (FILE *in, char *file, cha /* allocate basic structure for handling decoded content */ init_decoded_content (ct); - ce = ct->c_cefile; + ce = &ct->c_cefile; ci = &ct->c_ctinfo; set_id (ct, 0); @@@ -747,7 -753,7 +747,7 @@@ use_forw if (!folder) folder = add (getfolder (1), NULL); - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); for (ap = arguments; *ap; ap++) { cp = *ap; @@@ -785,7 -791,7 +785,7 @@@ if ((p = (CT) calloc (1, sizeof(*p))) == NULL) adios (NULL, "out of memory"); init_decoded_content (p); - pe = p->c_cefile; + pe = &p->c_cefile; if (get_ctinfo ("message/rfc822", p, 0) == NOTOK) done (1); p->c_type = CT_MESSAGE; @@@ -920,7 -926,7 +920,7 @@@ set_id (CT ct, int top static int compose_content (CT ct) { - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; switch (ct->c_type) { case CT_MULTIPART: @@@ -1157,7 -1163,7 +1157,7 @@@ scan_content (CT ct char *cp = NULL, buffer[BUFSIZ]; struct text *t = NULL; FILE *in = NULL; - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; /* * handle multipart by scanning all subparts @@@ -1626,7 -1632,7 +1626,7 @@@ calculate_digest (CT ct, int asciiP unsigned char digest[16]; unsigned char outbuf[25]; MD5_CTX mdContext; - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; char *infilename = ce->ce_file ? ce->ce_file : ct->c_file; FILE *in; diff --combined uip/mhcachesbr.c index 7fa27ab3,5f7e1479..f0185682 --- a/uip/mhcachesbr.c +++ b/uip/mhcachesbr.c @@@ -96,7 -96,7 +96,7 @@@ cache_content (CT ct { int cachetype; char *file, cachefile[BUFSIZ]; - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; if (!ct->c_id) { advise (NULL, "no %s: field in %s", ID_FIELD, ct->c_file); @@@ -344,19 -344,19 +344,19 @@@ use_raw make_intermediates (mapfile); mask = umask (writing == 2 ? 0077 : 0); - if (!(fp = lkfopen (mapfile, "a")) && errno == ENOENT) { + if (!(fp = lkfopendata (mapfile, "a")) && errno == ENOENT) { int fd; if ((fd = creat (mapfile, 0666)) != NOTOK) { close (fd); - fp = lkfopen (mapfile, "a"); + fp = lkfopendata (mapfile, "a"); } } umask (mask); if (!fp) return NOTOK; fprintf (fp, "%s: %s\n", mapname, id); - lkfclose (fp, mapfile); + lkfclosedata (fp, mapfile); done_map: if (*mapname == '/') @@@ -378,7 -378,7 +378,7 @@@ find_cache_aux2 (char *mapfile, char *i FILE *fp; m_getfld_state_t gstate = 0; - if (!(fp = lkfopen (mapfile, "r"))) + if (!(fp = lkfopendata (mapfile, "r"))) return NOTOK; for (;;) { @@@ -409,7 -409,7 +409,7 @@@ result = strcmp (id, dp); free (dp); if (result == 0) { - lkfclose (fp, mapfile); + lkfclosedata (fp, mapfile); return OK; } continue; @@@ -423,6 -423,6 +423,6 @@@ } m_getfld_state_destroy (&gstate); - lkfclose (fp, mapfile); + lkfclosedata (fp, mapfile); return NOTOK; } diff --combined uip/mhstoresbr.c index 56214167,6badafeb..57604b50 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@@ -872,7 -872,7 +872,7 @@@ output_content_folder (char *folder, ch struct msgs *mp; /* Read the folder. */ - if ((mp = folder_read (folder))) { + if ((mp = folder_read (folder, 0))) { /* Link file into folder */ msgnum = folder_addmsg (&mp, filename, 0, 0, 0, 0, (char *)0); } else { @@@ -1021,7 -1021,7 +1021,7 @@@ static voi get_storeproc (CT ct) { char **ap, **ep, *cp; - CI ci = &ct->c_ctinfo; + CI ci; /* * If the storeproc has already been defined, @@@ -1031,44 -1031,13 +1031,44 @@@ if (ct->c_storeproc) return; + /* + * If there's a Content-Disposition header and it has a filename, + * use that (RFC-2183). + */ + if (ct->c_dispo) { + char *cp = strchr (ct->c_dispo, ';'); + CI ci = calloc (1, sizeof *ci); + int status; + int found_filename = 0; + + if (cp && parse_header_attrs (ct->c_file, strlen (invo_name) + 2, &cp, + ci, &status) == OK) { + for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { + if (! strcasecmp (*ap, "filename") + && *(cp = *ep) != '/' + && *cp != '.' + && *cp != '|' + && *cp != '!' + && !strchr (cp, '%')) { + ct->c_storeproc = add (cp, NULL); + found_filename = 1; + } + free (*ap); + } + } + + free (ci); + if (found_filename) return; + } + /* * Check the attribute/value pairs, for the attribute "name". * If found, do a few sanity checks and copy the value into * the storeproc. */ + ci = &ct->c_ctinfo; for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (!mh_strcasecmp (*ap, "name") + if (! strcasecmp (*ap, "name") && *(cp = *ep) != '/' && *cp != '.' && *cp != '|' diff --combined uip/refile.c index 1d44b362,8dd04fb9..725a7ada --- a/uip/refile.c +++ b/uip/refile.c @@@ -12,7 -12,6 +12,7 @@@ #include #include #include +#include #define REFILE_SWITCHES \ X("draft", 0, DRAFTSW) \ @@@ -20,8 -19,6 +20,8 @@@ X("nolink", 0, NLINKSW) \ X("preserve", 0, PRESSW) \ X("nopreserve", 0, NPRESSW) \ + X("retainsequences", 0, RETAINSEQSSW) \ + X("noretainsequences", 0, NRETAINSEQSSW) \ X("unlink", 0, UNLINKSW) \ X("nounlink", 0, NUNLINKSW) \ X("src +folder", 0, SRCSW) \ @@@ -52,14 -49,13 +52,14 @@@ 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 (struct msgs *, char *, int, struct st_fold *, int, int, int); +static void copy_seqs (struct msgs *, int, struct msgs *, int); int main (int argc, char **argv) { - int linkf = 0, preserve = 0, filep = 0; + int linkf = 0, preserve = 0, retainseqs = 0, filep = 0; int foldp = 0, isdf = 0, unlink_msgs = 0; int i, msgnum; char *cp, *folder = NULL, buf[BUFSIZ]; @@@ -87,13 -83,13 +87,13 @@@ while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { - case AMBIGSW: + case AMBIGSW: ambigsw (cp, switches); done (1); - case UNKWNSW: + case UNKWNSW: adios (NULL, "-%s unknown\n", cp); - case HELPSW: + case HELPSW: snprintf (buf, sizeof(buf), "%s [msgs] [switches] +folder ...", invo_name); print_help (buf, switches, 1); @@@ -102,27 -98,20 +102,27 @@@ print_version(invo_name); done (0); - case LINKSW: + case LINKSW: linkf++; continue; - case NLINKSW: + case NLINKSW: linkf = 0; continue; - case PRESSW: + case PRESSW: preserve++; continue; - case NPRESSW: + case NPRESSW: preserve = 0; continue; + case RETAINSEQSSW: + retainseqs = 1; + continue; + case NRETAINSEQSSW: + retainseqs = 0; + continue; + case UNLINKSW: unlink_msgs++; continue; @@@ -130,7 -119,7 +130,7 @@@ unlink_msgs = 0; continue; - case SRCSW: + case SRCSW: if (folder) adios (NULL, "only one source folder at a time!"); if (!(cp = *argp++) || *cp == '-') @@@ -144,7 -133,7 +144,7 @@@ isdf = 0; files[filep++] = getcpy (m_draft (NULL, NULL, 1, &isdf)); continue; - case FILESW: + case FILESW: if (filep > NFOLDERS) adios (NULL, "only %d files allowed!", NFOLDERS); if (!(cp = *argp++) || *cp == '-') @@@ -152,11 -141,11 +152,11 @@@ files[filep++] = path (cp, TFILE); continue; - case RPROCSW: + case RPROCSW: if (!(rmmproc = *argp++) || *rmmproc == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; - case NRPRCSW: + case NRPRCSW: rmmproc = NULL; continue; } @@@ -188,7 -177,7 +188,7 @@@ 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 (0, files[i], 0, folders, foldp, preserve, 0)) done (1); /* If -nolink, then "remove" files */ if (!linkf) @@@ -206,7 -195,7 +206,7 @@@ adios (maildir, "unable to change directory to"); /* read source folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */ @@@ -231,8 -220,7 +231,8 @@@ 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 (mp, cp, retainseqs ? msgnum : 0, folders, foldp, + preserve, !linkf)) done (1); free (cp); } @@@ -294,7 -282,7 +294,7 @@@ opnfolds (struct st_fold *folders, int if (chdir (nmaildir) == NOTOK) adios (nmaildir, "unable to change directory to"); - if (!(mp = folder_read (fp->f_name))) + if (!(mp = folder_read (fp->f_name, 1))) adios (NULL, "unable to read folder %s", fp->f_name); mp->curmsg = 0; @@@ -359,13 -347,12 +359,13 @@@ remove_files (int filep, char **files /* - * Link (or copy) the message into each of - * the destination folders. + * Link (or copy) the message into each of the destination folders. + * If oldmsgnum is not 0, call copy_seqs(). */ static int -m_file (char *msgfile, struct st_fold *folders, int nfolders, int preserve, int refile) +m_file (struct msgs *mp, char *msgfile, int oldmsgnum, + struct st_fold *folders, int nfolders, int preserve, int refile) { int msgnum; struct st_fold *fp, *ep; @@@ -373,29 -360,6 +373,29 @@@ 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) return 1; + if (oldmsgnum) copy_seqs (mp, oldmsgnum, fp->f_mp, msgnum); } return 0; } + + +/* + * Copy sequence information for a refiled message to its + * new folder. Skip the cur sequence. + */ +static void +copy_seqs (struct msgs *oldmp, int oldmsgnum, struct msgs *newmp, int newmsgnum) +{ + char **seq; + int seqnum; + + for (seq = oldmp->msgattrs, seqnum = 0; *seq; ++seq, ++seqnum) { + if (strcmp (current, *seq)) { + assert (seqnum == seq_getnum (oldmp, *seq)); + if (in_sequence (oldmp, seqnum, oldmsgnum)) { + seq_addmsg (newmp, *seq, newmsgnum, + is_seq_private (oldmp, seqnum) ? 0 : 1, 0); + } + } + } +} diff --combined uip/rmm.c index 897c5028,02a55910..64d85cea --- a/uip/rmm.c +++ b/uip/rmm.c @@@ -13,8 -13,6 +13,8 @@@ #define RMM_SWITCHES \ X("unlink", 0, UNLINKSW) \ X("nounlink", 0, NUNLINKSW) \ + X("rmmproc program", 0, RPROCSW) \ + X("normmproc", 0, NRPRCSW) \ X("version", 0, VERSIONSW) \ X("help", 0, HELPSW) \ @@@ -52,13 -50,13 +52,13 @@@ main (int argc, char **argv while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { - case AMBIGSW: + case AMBIGSW: ambigsw (cp, switches); done (1); - case UNKWNSW: + case UNKWNSW: adios (NULL, "-%s unknown\n", cp); - case HELPSW: + case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]", invo_name); print_help (buf, switches, 1); @@@ -73,14 -71,6 +73,14 @@@ case NUNLINKSW: unlink_msgs = 0; continue; + + case RPROCSW: + if (!(rmmproc = *argp++) || *rmmproc == '-') + adios (NULL, "missing argument to %s", argp[-2]); + continue; + case NRPRCSW: + rmmproc = NULL; + continue; } } if (*cp == '+' || *cp == '@') { @@@ -104,7 -94,7 +104,7 @@@ adios (maildir, "unable to change directory to"); /* read folder and create message structure */ - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 1))) adios (NULL, "unable to read folder %s", folder); /* check for empty folder */