191 lines
7.4 KiB
Plaintext
191 lines
7.4 KiB
Plaintext
diff --git a/imap/mailbox.c b/imap/mailbox.c
|
|
index b1e7a99..6d75774 100644
|
|
--- a/imap/mailbox.c
|
|
+++ b/imap/mailbox.c
|
|
@@ -6388,6 +6388,39 @@ static int mailbox_reconstruct_uniqueid(struct mailbox *mailbox, int flags)
|
|
return r;
|
|
}
|
|
|
|
+static int mailbox_reconstruct_uidvalidity(struct mailbox *mailbox, int flags)
|
|
+{
|
|
+ int make_changes = flags & RECONSTRUCT_MAKE_CHANGES;
|
|
+ int prefer_mbentry = flags & RECONSTRUCT_PREFER_MBOXLIST;
|
|
+ mbentry_t *mbentry = NULL;
|
|
+
|
|
+ int r = mboxlist_lookup(mailbox->name, &mbentry, 0);
|
|
+ if (r) return r;
|
|
+
|
|
+ if (mailbox->i.uidvalidity != mbentry->uidvalidity) {
|
|
+ if (!mailbox->i.uidvalidity || (prefer_mbentry && mbentry->uidvalidity)) {
|
|
+ printf("Wrong uidvalidity in mailbox, fixing %s (%u -> %u)\n",
|
|
+ mailbox->name, mailbox->i.uidvalidity, mbentry->uidvalidity);
|
|
+ if (make_changes) {
|
|
+ mailbox->i.uidvalidity = mbentry->uidvalidity;
|
|
+ mailbox_index_dirty(mailbox);
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ printf("Wrong uidvalidity in mbentry, fixing %s (%u -> %u)\n",
|
|
+ mailbox->name, mbentry->uidvalidity, mailbox->i.uidvalidity);
|
|
+ if (make_changes) {
|
|
+ mbentry->uidvalidity = mailbox->i.uidvalidity;
|
|
+ r = mboxlist_update(mbentry, 0);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ mboxlist_entry_free(&mbentry);
|
|
+
|
|
+ return r;
|
|
+}
|
|
+
|
|
static int mailbox_reconstruct_acl(struct mailbox *mailbox, int flags)
|
|
{
|
|
int make_changes = flags & RECONSTRUCT_MAKE_CHANGES;
|
|
@@ -7109,6 +7142,11 @@ EXPORTED int mailbox_reconstruct(const char *name, int flags)
|
|
r = mailbox_reconstruct_uniqueid(mailbox, flags);
|
|
if (r) goto close;
|
|
|
|
+ if (flags & RECONSTRUCT_FIX_UIDVALIDITY) {
|
|
+ r = mailbox_reconstruct_uidvalidity(mailbox, flags);
|
|
+ if (r) goto close;
|
|
+ }
|
|
+
|
|
/* open and lock the annotation state */
|
|
r = mailbox_get_annotate_state(mailbox, ANNOTATE_ANY_UID, NULL);
|
|
if (r) {
|
|
diff --git a/imap/mailbox.h b/imap/mailbox.h
|
|
index fd04e41..0e1dac0 100644
|
|
--- a/imap/mailbox.h
|
|
+++ b/imap/mailbox.h
|
|
@@ -456,6 +456,7 @@ typedef enum _MsgInternalFlags {
|
|
#define RECONSTRUCT_REMOVE_ODDFILES (1<<7)
|
|
#define RECONSTRUCT_IGNORE_ODDFILES (1<<8)
|
|
#define RECONSTRUCT_PREFER_MBOXLIST (1<<9)
|
|
+#define RECONSTRUCT_FIX_UIDVALIDITY (1<<10)
|
|
|
|
#define MAX_CACHED_HEADER_SIZE 32 /* Max size of a cached header name */
|
|
|
|
diff --git a/imap/reconstruct.c b/imap/reconstruct.c
|
|
index dc6d0f6..82425a1 100644
|
|
--- a/imap/reconstruct.c
|
|
+++ b/imap/reconstruct.c
|
|
@@ -56,6 +56,7 @@
|
|
#include <netinet/in.h>
|
|
#include <sys/stat.h>
|
|
#include <libgen.h>
|
|
+#include <getopt.h>
|
|
#ifdef HAVE_ZLIB
|
|
#include <zlib.h>
|
|
#endif
|
|
@@ -129,6 +130,11 @@ static int reconstruct_flags = RECONSTRUCT_MAKE_CHANGES | RECONSTRUCT_DO_STAT;
|
|
static int setversion = 0;
|
|
static int updateuniqueids = 0;
|
|
|
|
+static struct option long_options[] = {
|
|
+ {"fix-uidvalidity", no_argument, NULL, 1},
|
|
+ {NULL, 0, NULL, 0}
|
|
+};
|
|
+
|
|
int main(int argc, char **argv)
|
|
{
|
|
int opt, i, r;
|
|
@@ -146,7 +152,7 @@ int main(int argc, char **argv)
|
|
|
|
construct_hash_table(&unqid_table, 2047, 1);
|
|
|
|
- while ((opt = getopt(argc, argv, "C:kp:rmfsxgGqRUMIoOnV:u")) != EOF) {
|
|
+ while ((opt = getopt_long(argc, argv, "C:kp:rmfsxgGqRUMIoOnV:u", long_options, NULL)) != EOF) {
|
|
switch (opt) {
|
|
case 'C': /* alt config file */
|
|
alt_config = optarg;
|
|
@@ -231,6 +237,10 @@ int main(int argc, char **argv)
|
|
setversion = atoi(optarg);
|
|
break;
|
|
|
|
+ case 1: /* --fix-uidvalidity */
|
|
+ reconstruct_flags |= RECONSTRUCT_FIX_UIDVALIDITY;
|
|
+ break;
|
|
+
|
|
default:
|
|
usage();
|
|
}
|
|
@@ -410,6 +420,7 @@ static void usage(void)
|
|
fprintf(stderr, "-M prefer mailboxes.db over cyrus.header\n");
|
|
fprintf(stderr, "-V <version> Change the cyrus.index minor version to the version specified\n");
|
|
fprintf(stderr, "-u give usernames instead of mailbox prefixes\n");
|
|
+ fprintf(stderr, "--fix-uidvalidity fix uidvalidity mismatches between mailbox index and mailboxes.db\n");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
diff --git a/docsrc/imap/reference/manpages/systemcommands/reconstruct.rst b/docsrc/imap/reference/manpages/systemcommands/reconstruct.rst
|
|
--- a/docsrc/imap/reference/manpages/systemcommands/reconstruct.rst
|
|
+++ b/docsrc/imap/reference/manpages/systemcommands/reconstruct.rst
|
|
@@ -18,10 +18,10 @@
|
|
**reconstruct** [ **-C** *config-file* ] [ **-p** *partition* ] [ **-x** ] [ **-r** ]
|
|
[ **-f** ] [ **-U** ] [ **-s** ] [ **-q** ] [ **-G** ] [ **-R** ] [ **-o** ]
|
|
- [ **-O** ] [ **-M** ] *mailbox*...
|
|
+ [ **-O** ] [ **-M** ] [ **--fix-uidvalidity** ] *mailbox*...
|
|
|
|
**reconstruct** [ **-C** *config-file* ] [ **-p** *partition* ] [ **-x** ] [ **-r** ]
|
|
[ **-f** ] [ **-U** ] [ **-s** ] [ **-q** ] [ **-G** ] [ **-R** ] [ **-o** ]
|
|
- [ **-O** ] [ **-M** ] **-u** *user*...
|
|
+ [ **-O** ] [ **-M** ] [ **--fix-uidvalidity** ] **-u** *user*...
|
|
|
|
**reconstruct** [ **-C** *config-file* ] [ **-p** *partition* ] [ **-r** ]
|
|
[ **-q** ] **-V** *version* *mailbox*...
|
|
@@ -161,6 +161,17 @@
|
|
.. option:: -u
|
|
|
|
Instead of mailbox prefixes, give usernames on the command line
|
|
+
|
|
+.. option:: --fix-uidvalidity
|
|
+
|
|
+ Detect and fix uidvalidity mismatches between the mailbox index (cyrus.index)
|
|
+ and the mailboxes database (mailboxes.db). If the index has a missing or zero
|
|
+ uidvalidity, it is copied from the database. Otherwise the database is updated
|
|
+ to match the index, unless **-M** is also given, in which case the index is
|
|
+ updated to match the database.
|
|
+
|
|
+ This option is specific to the Red Hat build of Cyrus IMAP and is not present
|
|
+ in the upstream release.
|
|
|
|
Examples
|
|
========
|
|
diff --git a/man/reconstruct.8 b/man/reconstruct.8
|
|
--- a/man/reconstruct.8
|
|
+++ b/man/reconstruct.8
|
|
@@ -41,10 +41,10 @@
|
|
\fBreconstruct\fP [ \fB\-C\fP \fIconfig\-file\fP ] [ \fB\-p\fP \fIpartition\fP ] [ \fB\-x\fP ] [ \fB\-r\fP ]
|
|
[ \fB\-f\fP ] [ \fB\-U\fP ] [ \fB\-s\fP ] [ \fB\-q\fP ] [ \fB\-G\fP ] [ \fB\-R\fP ] [ \fB\-o\fP ]
|
|
- [ \fB\-O\fP ] [ \fB\-M\fP ] \fImailbox\fP\&...
|
|
+ [ \fB\-O\fP ] [ \fB\-M\fP ] [ \fB\-\-fix\-uidvalidity\fP ] \fImailbox\fP\&...
|
|
|
|
\fBreconstruct\fP [ \fB\-C\fP \fIconfig\-file\fP ] [ \fB\-p\fP \fIpartition\fP ] [ \fB\-x\fP ] [ \fB\-r\fP ]
|
|
[ \fB\-f\fP ] [ \fB\-U\fP ] [ \fB\-s\fP ] [ \fB\-q\fP ] [ \fB\-G\fP ] [ \fB\-R\fP ] [ \fB\-o\fP ]
|
|
- [ \fB\-O\fP ] [ \fB\-M\fP ] \fB\-u\fP \fIuser\fP\&...
|
|
+ [ \fB\-O\fP ] [ \fB\-M\fP ] [ \fB\-\-fix\-uidvalidity\fP ] \fB\-u\fP \fIuser\fP\&...
|
|
|
|
\fBreconstruct\fP [ \fB\-C\fP \fIconfig\-file\fP ] [ \fB\-p\fP \fIpartition\fP ] [ \fB\-r\fP ]
|
|
[ \fB\-q\fP ] \fB\-V\fP \fIversion\fP \fImailbox\fP\&...
|
|
@@ -199,6 +199,19 @@
|
|
.B \-u
|
|
Instead of mailbox prefixes, give usernames on the command line
|
|
.UNINDENT
|
|
+.INDENT 0.0
|
|
+.TP
|
|
+.B \-\-fix\-uidvalidity
|
|
+Detect and fix uidvalidity mismatches between the mailbox index
|
|
+(cyrus.index) and the mailboxes database (mailboxes.db).
|
|
+If the index has a missing or zero uidvalidity, it is copied from the
|
|
+database. Otherwise the database is updated to match the index, unless
|
|
+\fB\-M\fP is also given, in which case the index is updated to match
|
|
+the database.
|
|
+.sp
|
|
+This option is specific to the Red Hat build of Cyrus IMAP and is not
|
|
+present in the upstream release.
|
|
+.UNINDENT
|
|
.SH EXAMPLES
|
|
.INDENT 0.0
|
|
.INDENT 3.5
|