diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-12-21 23:38:42 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-12-21 23:38:42 +0200 |
commit | 317bb197a7f288aa4d36d4af7849e90e14fd7a77 (patch) | |
tree | 583771cfe7e614587685e97b8feddd1eb66fbcdd | |
parent | 35b8dcfbe745d59faa4fde8d76b30c5781d5cd8d (diff) | |
download | mailutils-317bb197a7f288aa4d36d4af7849e90e14fd7a77.tar.gz mailutils-317bb197a7f288aa4d36d4af7849e90e14fd7a77.tar.bz2 |
MH: provide a mh_profile setting to control assignment of sequence numbers
The "Volatile-uidnext" setting controls how sequence numbers are allocated.
By default they increase monotonically. If Volatile-uidnext is set to
"true", each new incorporated message is assigned the sequence number equal
to that of the last message increased by one. When the last message in
the mailbox is deleted, the value of UIDNEXT is recalculated and
UIDVALIDITY is increased. This follows the behavior of traditional MH
implementations.
* doc/texinfo/mu-mh.texi: Document chnges.
* include/mailutils/sys/amd.h (MU_AMD_VOLATILE_UIDNEXT): New
constant.
* libmailutils/base/amd.c (amd_expunge): Reset uidvalidity and uidnext
if MU_AMD_VOLATILE_UIDNEXT capability is set and the last message
was removed.
* libproto/mh/mh.c (_mailbox_mh_init): New mh_profile setting
"Volatile-uidnext". If set to true, it instructs mailutils to
mimic the traditional MH behavior when assigning sequence number
to the new message.
* testsuite/mbop.c (main): Use MBOP_PRE_OPEN_HOOK (if defined) as
the name of the function to call before opening the mailbox.
* libproto/mh/tests/mbop.c (mbop_pre_open_hook): New function.
If the MH environment variable is set, take its value as the name
of the mh_profile and read settings from it.
* libproto/mh/tests/Makefile.am: Add uidvol.at
* libproto/mh/tests/atlocal.in: Unset MH.
* libproto/mh/tests/testsuite.at: Include uidvol.at
* libproto/mh/tests/uidvol.at: New file.
-rw-r--r-- | doc/texinfo/mu-mh.texi | 21 | ||||
-rw-r--r-- | include/mailutils/sys/amd.h | 9 | ||||
-rw-r--r-- | libmailutils/base/amd.c | 21 | ||||
-rw-r--r-- | libproto/mh/mh.c | 14 | ||||
-rw-r--r-- | libproto/mh/tests/Makefile.am | 3 | ||||
-rw-r--r-- | libproto/mh/tests/atlocal.in | 1 | ||||
-rw-r--r-- | libproto/mh/tests/mbop.c | 27 | ||||
-rw-r--r-- | libproto/mh/tests/testsuite.at | 1 | ||||
-rw-r--r-- | libproto/mh/tests/uidvol.at | 72 | ||||
-rw-r--r-- | testsuite/mbop.c | 5 |
10 files changed, 169 insertions, 5 deletions
diff --git a/doc/texinfo/mu-mh.texi b/doc/texinfo/mu-mh.texi index 840ddc347..29b35848a 100644 --- a/doc/texinfo/mu-mh.texi +++ b/doc/texinfo/mu-mh.texi @@ -26,6 +26,27 @@ distribution directory. @subsection Major differences between Mailutils MH and other MH implementations @enumerate 1 +@item Sequence numbers increase monotonically; + +Message sequence numbers are used as UIDs and thus increase +monotonically. This means, in particular, that if your +inbox has messages in the range @samp{@var{X}--@var{Y}} and you +delete all messages and then incorporate new mail, the first +incorporated message will be assigned sequence number @samp{@var{Y} + 1} +(other MH implementations will assign @samp{1}). If this behavior +bugs you, add the following setting to your @file{.mh_profile}: + +@example +Volatile-uidnext: true +@end example + +You can always renumber your messages starting from @samp{1} by +running + +@example +folder -pack=1 +@end example + @item UUCP addresses are not supported; @item Mailutils supports a set of new format specifications diff --git a/include/mailutils/sys/amd.h b/include/mailutils/sys/amd.h index 2affcba50..34076e11f 100644 --- a/include/mailutils/sys/amd.h +++ b/include/mailutils/sys/amd.h @@ -66,7 +66,14 @@ struct _amd_message }; /* AMD capabilities */ -#define MU_AMD_STATUS 0x01 /* format keeps status flags */ +#define MU_AMD_STATUS 0x01 /* format keeps status flags */ +#define MU_AMD_VOLATILE_UIDNEXT 0x02 /* Reset UIDNEXT and UIDVALIDITY + when the last message is removed. This helps implement the traditional + MH behavior: sequence number for the new message is computed as that of + the last message incremented by one. Normally this behavior is enabled + by setting the 'Volatile-uidnext' parameter in mh_profile to 'true'. + See _mailbox_mh_init in libproto/mh/mh.c. +*/ #define MU_AMD_F_INIT_SCAN 0x01 /* Done initial scanning */ #define MU_AMD_F_PROP 0x02 /* prop file existed */ diff --git a/libmailutils/base/amd.c b/libmailutils/base/amd.c index ee32d2917..52531536f 100644 --- a/libmailutils/base/amd.c +++ b/libmailutils/base/amd.c @@ -1410,7 +1410,16 @@ amd_expunge (mu_mailbox_t mailbox) if (expcount) { + int reset_uidvalidity; + last_expunged++; + + /* See the description of MU_AMD_VOLATILE_UIDNEXT in amd.h for + details. + */ + reset_uidvalidity = (amd->capabilities & MU_AMD_VOLATILE_UIDNEXT) + && last_expunged == amd->msg_count; + do { size_t j; @@ -1425,6 +1434,18 @@ amd_expunge (mu_mailbox_t mailbox) ; } while (last_expunged); + + if (reset_uidvalidity) + { + /* + * The following is equivalent to + * mu_mailbox_uidvalidity_reset (amd->mailbox); + */ + + struct timeval tv; + gettimeofday (&tv, NULL); + amd_set_uidvalidity (amd->mailbox, tv.tv_sec); + } } if (updated && !amd->mailbox_size) diff --git a/libproto/mh/mh.c b/libproto/mh/mh.c index 338ea95f1..f83b69027 100644 --- a/libproto/mh/mh.c +++ b/libproto/mh/mh.c @@ -503,7 +503,8 @@ _mailbox_mh_init (mu_mailbox_t mailbox) { int rc; struct _amd_data *amd; - + char const *p; + rc = amd_init_mailbox (mailbox, sizeof (struct _amd_data), &amd); if (rc) return rc; @@ -526,7 +527,16 @@ _mailbox_mh_init (mu_mailbox_t mailbox) if (mu_mhprop_get_value (mu_mh_profile, "rmmproc", NULL)) amd->delete_msg = _mh_msg_delete; - + + if ((p = mu_mhprop_get_value (mu_mh_profile, "volatile-uidnext", NULL)) != NULL) + { + int res; + if (mu_str_to_c (p, mu_c_bool, &res, NULL)) + mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, + ("Value of Volatile-UIDNEXT is not a boolean")); + else if (res) + amd->capabilities |= MU_AMD_VOLATILE_UIDNEXT; + } return 0; } diff --git a/libproto/mh/tests/Makefile.am b/libproto/mh/tests/Makefile.am index fae4351e1..5e4bae891 100644 --- a/libproto/mh/tests/Makefile.am +++ b/libproto/mh/tests/Makefile.am @@ -47,7 +47,8 @@ TESTSUITE_AT += \ qget.at\ uid.at\ uidnext.at\ - uidvalidity.at + uidvalidity.at\ + uidvol.at diff --git a/libproto/mh/tests/atlocal.in b/libproto/mh/tests/atlocal.in index fd440e2ad..f1a08c563 100644 --- a/libproto/mh/tests/atlocal.in +++ b/libproto/mh/tests/atlocal.in @@ -4,3 +4,4 @@ PATH=@abs_builddir@:@abs_top_builddir@/testsuite:$PATH spooldir=$abs_top_srcdir/testsuite/spool/ +unset MH diff --git a/libproto/mh/tests/mbop.c b/libproto/mh/tests/mbop.c index 790c72773..3918adbab 100644 --- a/libproto/mh/tests/mbop.c +++ b/libproto/mh/tests/mbop.c @@ -1,3 +1,30 @@ +#include <stdlib.h> +#include <mailutils/alloc.h> +#include <mailutils/property.h> +#include <mailutils/diag.h> +#include <mailutils/mh.h> + #define MBOP_RECORD mu_mh_record #define MBOP_SCHEME "mh" +#define MBOP_PRE_OPEN_HOOK mbop_pre_open_hook +static void +mbop_pre_open_hook (void) +{ + char *env = getenv ("MH"); + if (env && env[0]) + { + struct mu_mh_prop *mhprop; + int rc; + + mhprop = mu_zalloc (sizeof (mhprop[0])); + mhprop->filename = env; + mhprop->ro = 0; + rc = mu_property_create_init (&mu_mh_profile, mu_mh_property_init, mhprop); + if (rc) + { + mu_diag_funcall (MU_DIAG_ERROR, "mu_property_create_init", env, rc); + exit (1); + } + } +} #include "testsuite/mbop.c" diff --git a/libproto/mh/tests/testsuite.at b/libproto/mh/tests/testsuite.at index 33b16c70e..8ce7d50a6 100644 --- a/libproto/mh/tests/testsuite.at +++ b/libproto/mh/tests/testsuite.at @@ -34,6 +34,7 @@ m4_include([notify.at]) m4_include([delete.at]) m4_include([uidnext.at]) +m4_include([uidvol.at]) # Local Variables: # mode: autotest diff --git a/libproto/mh/tests/uidvol.at b/libproto/mh/tests/uidvol.at new file mode 100644 index 000000000..d03171169 --- /dev/null +++ b/libproto/mh/tests/uidvol.at @@ -0,0 +1,72 @@ +# GNU Mailutils -- a suite of utilities for electronic mail -*- autotest -*- +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This library is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +AT_SETUP([Volatile UIDs (traditional MH behavior)]) + +# Create the test MH mailbox +AT_CHECK([mbox2dir -m -p -v 10 -u inbox $spooldir/mbox1]) + +# Check its current UID settings +AT_CHECK([mbop -m inbox uidnext \; uidvalidity], +[0], +[uidnext: 6 +uidvalidity: 10 +]) + +# Request traditional MH behavior. +AT_DATA([mh_profile], +[Volatile-uidnext: true +]) + +# Remove the penultimate message. This should not affect uidvalidity. +AT_CHECK([MH=mh_profile mbop -m inbox 4 \; set_deleted \; expunge], +[0], +[4 current message +4 set_deleted: OK +expunge: OK +]) + +# Check if uidnext and uidvalidity remain the same. +AT_CHECK([mbop -m inbox uidnext \; uidvalidity], +[0], +[uidnext: 6 +uidvalidity: 10 +]) + +# Remove the last message. With Volatile-uidnext on, this will reset +# uidnext to 4 (sequence number of the last message plus one) and +# increase uidvalidity, +AT_CHECK([MH=mh_profile mbop -m inbox 4 \; set_deleted \; expunge], +[0], +[4 current message +4 set_deleted: OK +expunge: OK +]) + +# Check if uidnext is computed correctly. +AT_CHECK([MH=mh_profile mbop -m inbox uidnext], +[0], +[uidnext: 4 +]) + +# Check that uidvalidity has changed. +# FIXME: Better check that it has *increased*. +AT_CHECK([MH=mh_profile mbop -m inbox uidvalidity | grep -v '^uid-validity:10$' | grep uid-validity || true]) + +AT_CLEANUP + + + diff --git a/testsuite/mbop.c b/testsuite/mbop.c index 1af0ebf6e..e3ee0f8d3 100644 --- a/testsuite/mbop.c +++ b/testsuite/mbop.c @@ -621,7 +621,10 @@ main (int argc, char **argv) mbox_flags = MU_STREAM_READ; else mbox_flags = MU_STREAM_RDWR; - + +#ifdef MBOP_PRE_OPEN_HOOK + MBOP_PRE_OPEN_HOOK (); +#endif MU_ASSERT (mu_mailbox_create_default (&env.mbx, env.mbxname)); MU_ASSERT (mu_mailbox_open (env.mbx, mbox_flags)); |