[SVN] r639 - in
/branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches:
0001-upstream-update-to-post-2-3-7-cvs-head.dpatch 00list
debian at incase.de
debian at incase.de
Tue Oct 3 13:14:24 UTC 2006
Author: farzy
Date: Tue Oct 3 15:14:19 2006
New Revision: 639
URL: https://mail.incase.de/viewcvs?rev=639&root=cyrus22&view=rev
Log:
Some upstream patches to version 2.3.7:
* Update changes.html.
* replication related patches.
* New option IMAPOPT_IMPROVED_MBOXLIST_SORT to change sort order
with regards to special characters ('-', ' '...).
* Better compatibility with the ACL rights of Cyrus Imapd 2.2
(RFC 4314).
* My own patch to 'squatter.c' to ignore remote mailboxes gracefully
* Minor logging corrections to imap/tls.c and imtest/imtest.c
* Double string copy in ptclient/ldap.c.
Added:
branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch (with props)
Modified:
branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/00list
Added: branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch
URL: https://mail.incase.de/viewcvs/branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch?rev=639&root=cyrus22&view=auto
==============================================================================
--- branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch (added)
+++ branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch Tue Oct 3 15:14:19 2006
@@ -1,0 +1,1779 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 0001-upstream-update-to-post-2-3-7-cvs-head.dpatch by Farzad FARID <ffarid at pragmatic-source.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Update to CVS HEAD as of 2006-09-27, minus the saslclient.c patch that
+## DP: does not work, and the CMU specific changes, including:
+## DP: * Update changes.html.
+## DP: * replication related patches.
+## DP: * New option IMAPOPT_IMPROVED_MBOXLIST_SORT to change sort order
+## DP: with regards to special characters ('-', ' '...).
+## DP: * Better compatibility with the ACL rights of Cyrus Imapd 2.2
+## DP: (RFC 4314).
+## DP: * My own patch to 'squatter.c' to ignore remote mailboxes gracefully
+## DP: * Minor logging corrections to imap/tls.c and imtest/imtest.c
+## DP: * Double string copy in ptclient/ldap.c.
+
+ at DPATCH@
+diff -urNad cyrus-imapd-2.3-2.3.7~/doc/changes.html cyrus-imapd-2.3-2.3.7/doc/changes.html
+--- cyrus-imapd-2.3-2.3.7~/doc/changes.html 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/doc/changes.html 2006-09-27 18:53:16.000000000 +0200
+@@ -1,6 +1,6 @@
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+-<!-- $Id: changes.html,v 1.71.2.50 2006/06/27 15:58:40 murch Exp $ -->
++<!-- $Id: changes.html,v 1.71.2.51 2006/08/10 18:22:49 murch Exp $ -->
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta name="generator" content="HTML Tidy, see www.w3.org" />
+@@ -8,6 +8,17 @@
+ </head>
+ <body>
+
++<h1>Changes to the Cyrus IMAP Server since 2.3.7</h1>
++<ul>
++<li>Added <tt>improved_mboxlist_sort</tt> option which fixes LIST/LSUB
++problem with characters like <tt>'-'</tt> and <tt>' '</tt> in mailbox
++names. See <tt>imapd.conf.5</tt> for details</li>
++<li>Fixed problem with DELETEing mailboxes with split metadata
++directories.</li>
++<li>Fixed problem with replication and COPYing \Seen messages.</li>
++<li>Fixed miscellaneous bugs and build issues.</li>
++</ul>
++
+ <h1>Changes to the Cyrus IMAP Server since 2.3.6</h1>
+ <ul>
+ <li>Fixed problems with replication and virtual domains.</li>
+@@ -2140,7 +2151,7 @@
+ </ul>
+
+ <hr />
+-last modified: $Date: 2006/06/27 15:58:40 $ <br />
++last modified: $Date: 2006/08/10 18:22:49 $ <br />
+ <a href="index.html">Return</a> to the Cyrus IMAP Server Home Page
+ </body>
+ </html>
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/annotate.c cyrus-imapd-2.3-2.3.7/imap/annotate.c
+--- cyrus-imapd-2.3-2.3.7~/imap/annotate.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/annotate.c 2006-09-27 18:53:16.000000000 +0200
+@@ -40,7 +40,7 @@
+ *
+ */
+ /*
+- * $Id: annotate.c,v 1.16.2.16 2006/06/01 13:23:23 murch Exp $
++ * $Id: annotate.c,v 1.16.2.17 2006/07/11 14:36:23 murch Exp $
+ */
+
+ #include <config.h>
+@@ -1725,6 +1725,8 @@
+
+ mailbox_close(&mailbox);
+
++ if (!r) sync_log_mailbox(int_mboxname);
++
+ return r;
+
+ }
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/backend.c cyrus-imapd-2.3-2.3.7/imap/backend.c
+--- cyrus-imapd-2.3-2.3.7~/imap/backend.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/backend.c 2006-09-27 18:53:16.000000000 +0200
+@@ -39,7 +39,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: backend.c,v 1.16.2.18 2006/06/27 15:58:42 murch Exp $ */
++/* $Id: backend.c,v 1.16.2.19 2006/08/01 21:26:07 murch Exp $ */
+
+ #include <config.h>
+
+@@ -276,7 +276,7 @@
+ int sock = -1;
+ int r;
+ int err = -1;
+- struct addrinfo hints, *res0 = NULL, *res1 = NULL, *res;
++ struct addrinfo hints, *res0 = NULL, *res;
+ struct sockaddr_un sunsock;
+ char buf[2048], *mechlist = NULL;
+ struct sigaction action;
+@@ -322,12 +322,6 @@
+ if (!ret_backend) free(ret);
+ return NULL;
+ }
+- /* Get addrinfo struct for local interface. */
+- err = getaddrinfo(config_servername, NULL, &hints, &res1);
+- if(err) {
+- syslog(LOG_ERR, "getaddrinfo(%s) failed: %s",
+- config_servername, gai_strerror(err));
+- }
+ }
+
+ /* Setup timeout */
+@@ -344,15 +338,6 @@
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock < 0)
+ continue;
+- /* Bind to local interface. */
+- if (!err) {
+- if (bind(sock, res1->ai_addr, res1->ai_addrlen) < 0) {
+- struct sockaddr_in *local_sockaddr = (struct sockaddr_in *) res1->ai_addr;
+- syslog(LOG_ERR, "failed to bind to address %s: %s",
+- inet_ntoa(local_sockaddr->sin_addr), strerror(errno));
+- }
+- freeaddrinfo(res1);
+- }
+ alarm(config_getint(IMAPOPT_CLIENT_TIMEOUT));
+ if (connect(sock, res->ai_addr, res->ai_addrlen) >= 0)
+ break;
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/imapd.c cyrus-imapd-2.3-2.3.7/imap/imapd.c
+--- cyrus-imapd-2.3-2.3.7~/imap/imapd.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/imapd.c 2006-09-27 18:53:16.000000000 +0200
+@@ -38,7 +38,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: imapd.c,v 1.443.2.84 2006/07/03 13:22:41 murch Exp $ */
++/* $Id: imapd.c,v 1.443.2.89 2006/09/08 20:19:19 murch Exp $ */
+
+ #include <config.h>
+
+@@ -135,7 +135,7 @@
+ /* are we doing virtdomains with multiple IPs? */
+ static int disable_referrals;
+
+-/* has the client issued an RLIST or RLSUB? */
++/* has the client issued an RLIST, RLSUB, or LIST (REMOTE)? */
+ static int supports_referrals;
+
+ /* end PROXY STUFF */
+@@ -1553,7 +1553,6 @@
+ /* snmp_increment(RECONSTRUCT_COUNT, 1); */
+ }
+ else if (!strcmp(cmd.s, "Rlist")) {
+- supports_referrals = !disable_referrals;
+ c = getastring(imapd_in, imapd_out, &arg1);
+ if (c != ' ') goto missingargs;
+ c = getastring(imapd_in, imapd_out, &arg2);
+@@ -1564,7 +1563,6 @@
+ /* snmp_increment(LIST_COUNT, 1); */
+ }
+ else if (!strcmp(cmd.s, "Rlsub")) {
+- supports_referrals = !disable_referrals;
+ c = getastring(imapd_in, imapd_out, &arg1);
+ if (c != ' ') goto missingargs;
+ c = getastring(imapd_in, imapd_out, &arg2);
+@@ -3126,6 +3124,16 @@
+ r = message_copy_strict(imapd_in, curstage->f, size, curstage->binary);
+ }
+ totalsize += size;
++ /* If this is a non-BINARY message, close the stage file.
++ * Otherwise, leave it open so we can encode the binary parts.
++ *
++ * XXX For BINARY MULTIAPPEND, we may have to close the stage files
++ * anyways to avoid too many open files.
++ */
++ if (!curstage->binary) {
++ fclose(curstage->f);
++ curstage->f = NULL;
++ }
+
+ /* if we see a SP, we're trying to append more than one message */
+
+@@ -3159,8 +3167,9 @@
+ for (i = 0; !r && i < numstage; i++) {
+ if (stage[i]->binary) {
+ r = message_parse_binary_file(stage[i]->f, &body);
++ fclose(stage[i]->f);
++ stage[i]->f = NULL;
+ }
+- fclose(stage[i]->f); stage[i]->f = NULL;
+ if (!r) {
+ r = append_fromstage(&mailbox, &body, stage[i]->stage,
+ stage[i]->internaldate,
+@@ -4729,7 +4738,7 @@
+ ©uid, !config_getswitch(IMAPOPT_SINGLEINSTANCESTORE));
+ }
+
+- index_check(imapd_mailbox, usinguid, 0);
++ imapd_check(NULL, usinguid, 0);
+
+ done:
+ if (r && !(usinguid && r == IMAP_NO_NOSUCHMSG)) {
+@@ -5684,6 +5693,8 @@
+ struct auth_state *auth_state, int (*proc)(),
+ void *rock, int force);
+
++ if (listopts & LIST_REMOTE) supports_referrals = !disable_referrals;
++
+ /* Ignore the reference argument?
+ (the behavior in 1.5.10 & older) */
+ if (ignorereference == 0) {
+@@ -5885,7 +5896,6 @@
+ int r, access;
+ char *acl;
+ char *rights, *nextid;
+- char str[ACL_MAXSTR];
+
+ r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name,
+ imapd_userid, mailboxname);
+@@ -5928,7 +5938,6 @@
+ prot_printf(imapd_out, " ");
+ printastring(acl);
+ prot_printf(imapd_out, " ");
+- rights = cyrus_acl_masktostr(cyrus_acl_strtomask(rights), str, 1);
+ printastring(rights);
+ acl = nextid;
+ }
+@@ -6001,11 +6010,11 @@
+
+ /* calculate optional rights */
+ cyrus_acl_masktostr(implicit ^ (canon_identifier ? ACL_FULL : 0),
+- optional, 1);
++ optional);
+
+ /* build the rights string */
+ if (implicit) {
+- cyrus_acl_masktostr(implicit, rightsdesc, 1);
++ cyrus_acl_masktostr(implicit, rightsdesc);
+ }
+ else {
+ strcpy(rightsdesc, "\"\"");
+@@ -6080,7 +6089,7 @@
+ prot_printf(imapd_out, "* MYRIGHTS ");
+ printastring(name);
+ prot_printf(imapd_out, " ");
+- printastring(cyrus_acl_masktostr(rights, str, 1));
++ printastring(cyrus_acl_masktostr(rights, str));
+ prot_printf(imapd_out, "\r\n%s OK %s\r\n", tag,
+ error_message(IMAP_OK_COMPLETED));
+ }
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/index.c cyrus-imapd-2.3-2.3.7/imap/index.c
+--- cyrus-imapd-2.3-2.3.7~/imap/index.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/index.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ *
+ */
+ /*
+- * $Id: index.c,v 1.199.2.28 2006/07/05 19:51:30 murch Exp $
++ * $Id: index.c,v 1.199.2.31 2006/09/26 12:44:53 murch Exp $
+ */
+ #include <config.h>
+
+@@ -1251,6 +1251,7 @@
+ unsigned long uidvalidity;
+ unsigned long startuid, num;
+ long docopyuid;
++ int haveseen = 0;
+
+ *copyuidp = NULL;
+
+@@ -1262,6 +1263,7 @@
+
+ for (i = 0; i < copyargs.nummsg; i++) {
+ totalsize += copyargs.copymsg[i].size;
++ haveseen |= copyargs.copymsg[i].seen;
+ }
+
+ r = append_setup(&append_mailbox, name, MAILBOX_FORMAT_NORMAL,
+@@ -1275,7 +1277,11 @@
+ if (!r) append_commit(&append_mailbox, totalsize,
+ &uidvalidity, &startuid, &num);
+
+- if (!r) sync_log_mailbox_double(mailbox->name, name);
++ if (!r) {
++ sync_log_mailbox_double(mailbox->name, name);
++ /* if any messages are seen then we need to sync the seen state */
++ if (haveseen) sync_log_seen(imapd_userid, name);
++ }
+
+ if (!r && docopyuid) {
+ copyuid_size = 1024;
+@@ -1808,6 +1814,12 @@
+ {
+ int n;
+
++ /* If no data, output NIL */
++ if (!msg_base) {
++ prot_printf(pout, "NIL");
++ return;
++ }
++
+ /* partial fetch: adjust 'size' */
+ if (octet_count) {
+ if (size <= start_octet) {
+@@ -1819,8 +1831,8 @@
+ if (size > octet_count) size = octet_count;
+ }
+
+- /* If no data, output null quoted string */
+- if (!msg_base || size == 0) {
++ /* If zero-length data, output empty quoted string */
++ if (size == 0) {
+ prot_printf(pout, "\"\"");
+ return;
+ }
+@@ -1943,7 +1955,7 @@
+ offset = CACHE_ITEM_BIT32(cacheitem);
+ size = CACHE_ITEM_BIT32(cacheitem + CACHE_ITEM_SIZE_SKIP);
+
+- if ((p = strstr(resp, "BINARY"))) {
++ if (msg_base && (p = strstr(resp, "BINARY"))) {
+ /* BINARY or BINARY.SIZE */
+ int encoding = CACHE_ITEM_BIT32(cacheitem + 2 * 4) & 0xff;
+
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/mailbox.c cyrus-imapd-2.3-2.3.7/imap/mailbox.c
+--- cyrus-imapd-2.3-2.3.7~/imap/mailbox.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/mailbox.c 2006-09-27 18:53:16.000000000 +0200
+@@ -38,7 +38,7 @@
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+- * $Id: mailbox.c,v 1.147.2.36 2006/06/02 18:55:06 murch Exp $
++ * $Id: mailbox.c,v 1.147.2.38 2006/08/04 14:40:39 murch Exp $
+ *
+ */
+
+@@ -982,25 +982,25 @@
+
+ buf = (unsigned char*) mailbox->index_base + offset;
+
+- record->uid = htonl(*((bit32 *)(buf+OFFSET_UID)));
+- record->internaldate = htonl(*((bit32 *)(buf+OFFSET_INTERNALDATE)));
+- record->sentdate = htonl(*((bit32 *)(buf+OFFSET_SENTDATE)));
+- record->size = htonl(*((bit32 *)(buf+OFFSET_SIZE)));
+- record->header_size = htonl(*((bit32 *)(buf+OFFSET_HEADER_SIZE)));
+- record->content_offset = htonl(*((bit32 *)(buf+OFFSET_CONTENT_OFFSET)));
+- record->cache_offset = htonl(*((bit32 *)(buf+OFFSET_CACHE_OFFSET)));
+- record->last_updated = htonl(*((bit32 *)(buf+OFFSET_LAST_UPDATED)));
+- record->system_flags = htonl(*((bit32 *)(buf+OFFSET_SYSTEM_FLAGS)));
++ record->uid = ntohl(*((bit32 *)(buf+OFFSET_UID)));
++ record->internaldate = ntohl(*((bit32 *)(buf+OFFSET_INTERNALDATE)));
++ record->sentdate = ntohl(*((bit32 *)(buf+OFFSET_SENTDATE)));
++ record->size = ntohl(*((bit32 *)(buf+OFFSET_SIZE)));
++ record->header_size = ntohl(*((bit32 *)(buf+OFFSET_HEADER_SIZE)));
++ record->content_offset = ntohl(*((bit32 *)(buf+OFFSET_CONTENT_OFFSET)));
++ record->cache_offset = ntohl(*((bit32 *)(buf+OFFSET_CACHE_OFFSET)));
++ record->last_updated = ntohl(*((bit32 *)(buf+OFFSET_LAST_UPDATED)));
++ record->system_flags = ntohl(*((bit32 *)(buf+OFFSET_SYSTEM_FLAGS)));
+ for (n = 0; n < MAX_USER_FLAGS/32; n++) {
+- record->user_flags[n] = htonl(*((bit32 *)(buf+OFFSET_USER_FLAGS+4*n)));
++ record->user_flags[n] = ntohl(*((bit32 *)(buf+OFFSET_USER_FLAGS+4*n)));
+ }
+- record->content_lines = htonl(*((bit32 *)(buf+OFFSET_CONTENT_LINES)));
+- record->cache_version = htonl(*((bit32 *)(buf+OFFSET_CACHE_VERSION)));
++ record->content_lines = ntohl(*((bit32 *)(buf+OFFSET_CONTENT_LINES)));
++ record->cache_version = ntohl(*((bit32 *)(buf+OFFSET_CACHE_VERSION)));
+ message_uuid_unpack(&record->uuid, buf+OFFSET_MESSAGE_UUID);
+ #ifdef HAVE_LONG_LONG_INT
+- record->modseq = htonll(*((bit64 *)(buf+OFFSET_MODSEQ_64)));
++ record->modseq = ntohll(*((bit64 *)(buf+OFFSET_MODSEQ_64)));
+ #else
+- record->modseq = htonl(*((bit32 *)(buf+OFFSET_MODSEQ)));
++ record->modseq = ntohl(*((bit32 *)(buf+OFFSET_MODSEQ)));
+ #endif
+ return 0;
+ }
+@@ -2670,16 +2670,70 @@
+ }
+
+ /*
++ * Remove all files in directory
++ */
++static void mailbox_delete_files(char *path)
++{
++ DIR *dirp;
++ struct dirent *f;
++ char buf[MAX_MAILBOX_PATH+1];
++ char *tail;
++
++ strlcpy(buf, path, sizeof(buf));
++
++ if(strlen(buf) >= sizeof(buf) - 2) {
++ syslog(LOG_ERR, "IOERROR: Path too long (%s)", buf);
++ fatal("path too long", EC_OSFILE);
++ }
++
++ tail = buf + strlen(buf);
++ *tail++ = '/';
++ *tail = '\0';
++ dirp = opendir(path);
++ if (dirp) {
++ while ((f = readdir(dirp))!=NULL) {
++ if (f->d_name[0] == '.'
++ && (f->d_name[1] == '\0'
++ || (f->d_name[1] == '.' &&
++ f->d_name[2] == '\0'))) {
++ /* readdir() can return "." or "..", and I got a bug report
++ that SCO might blow the file system to smithereens if we
++ unlink(".."). Let's not do that. */
++ continue;
++ }
++
++ if(strlen(buf) + strlen(f->d_name) >= sizeof(buf)) {
++ syslog(LOG_ERR, "IOERROR: Path too long (%s + %s)",
++ buf, f->d_name);
++ fatal("Path too long", EC_OSFILE);
++ }
++ strcpy(tail, f->d_name);
++ unlink(buf);
++ *tail = '\0';
++ }
++ closedir(dirp);
++ }
++}
++
++/* Callback for use by cmd_delete */
++static int chkchildren(char *name,
++ int matchlen __attribute__((unused)),
++ int maycreate __attribute__((unused)),
++ void *rock __attribute__((unused)))
++{
++ return CYRUSDB_DONE;
++}
++
++/*
+ * Delete and close the mailbox 'mailbox'. Closes 'mailbox' whether
+ * or not the deletion was successful. Requires a locked mailbox.
+ */
+ int mailbox_delete(struct mailbox *mailbox, int delete_quota_root)
+ {
+ int r, rquota = 0;
+- DIR *dirp;
+- struct dirent *f;
+- char buf[MAX_MAILBOX_PATH+1], *path;
+- char *tail;
++ char nbuf[MAX_MAILBOX_NAME+1];
++ char pbuf[MAX_MAILBOX_PATH+1], mbuf[MAX_MAILBOX_PATH+1];
++ char *ntail, *ptail, *mtail = NULL;
+ struct txn *tid = NULL;
+
+ /* Ensure that we are locked */
+@@ -2711,55 +2765,60 @@
+ quota_commit(&tid);
+ }
+
+- /* remove data (message file) directory */
+- path = mailbox->path;
++ /* Flush data (message file) directory */
++ mailbox_delete_files(mailbox->path);
++ strlcpy(pbuf, mailbox->path, sizeof(pbuf));
++ ptail = pbuf + strlen(pbuf);
+
++ /* Flush metadata directory */
++ if (mailbox->mpath) {
++ mailbox_delete_files(mailbox->mpath);
++ strlcpy(mbuf, mailbox->mpath, sizeof(mbuf));
++ mtail = mbuf + strlen(mbuf);
++ }
++
++ strlcpy(nbuf, mailbox->name, sizeof(nbuf));
++ ntail = nbuf + strlen(nbuf);
+ do {
+- /* remove all files in directory */
+- strlcpy(buf, path, sizeof(buf));
++ /* Check if the mailbox has children */
++ strcpy(ntail, ".*");
++ r = mboxlist_findall(NULL, nbuf, 1, NULL, NULL, chkchildren, NULL);
++ if (r != 0) break; /* We short-circuit with CYRUSDB_DONE */
+
+- if(strlen(buf) >= sizeof(buf) - 2) {
+- syslog(LOG_ERR, "IOERROR: Path too long (%s)", buf);
+- fatal("path too long", EC_OSFILE);
++ /* No children, remove mailbox spool dir(s) */
++ if (rmdir(pbuf)) {
++ syslog(LOG_NOTICE,
++ "Remove of supposedly empty directory %s failed: %m",
++ pbuf);
+ }
++ ptail = strrchr(pbuf, '/');
++ *ptail ='\0';
+
+- tail = buf + strlen(buf);
+- *tail++ = '/';
+- *tail = '\0';
+- dirp = opendir(path);
+- if (dirp) {
+- while ((f = readdir(dirp))!=NULL) {
+- if (f->d_name[0] == '.'
+- && (f->d_name[1] == '\0'
+- || (f->d_name[1] == '.' &&
+- f->d_name[2] == '\0'))) {
+- /* readdir() can return "." or "..", and I got a bug report
+- that SCO might blow the file system to smithereens if we
+- unlink(".."). Let's not do that. */
+- continue;
+- }
+-
+- if(strlen(buf) + strlen(f->d_name) >= sizeof(buf)) {
+- syslog(LOG_ERR, "IOERROR: Path too long (%s + %s)",
+- buf, f->d_name);
+- fatal("Path too long", EC_OSFILE);
+- }
+- strcpy(tail, f->d_name);
+- unlink(buf);
+- *tail = '\0';
++ if (mtail) {
++ if (rmdir(mbuf)) {
++ syslog(LOG_NOTICE,
++ "Remove of supposedly empty directory %s failed: %m",
++ mbuf);
+ }
+- closedir(dirp);
++ mtail = strrchr(mbuf, '/');
++ *mtail ='\0';
+ }
+
+- /* Remove empty directories, going up path */
+- tail--;
+- do {
+- *tail = '\0';
+- } while (rmdir(buf) == 0 && (tail = strrchr(buf, '/')));
+-
+- /* remove metadata directory (if exists) */
+- } while (mailbox->mpath && (path != mailbox->mpath) &&
+- (path = mailbox->mpath));
++ /* Check if parent mailbox exists */
++ *ntail = '\0';
++ ntail = strrchr(nbuf, '.');
++ if (!ntail || strchr(ntail, '!')) {
++ /* Hit top of hierarchy or domain separator */
++ break;
++ }
++ *ntail = '\0';
++ if (!strcmp(nbuf, "user") ||
++ ((ntail - nbuf > 5) && !strcmp(ntail-5, "!user"))) {
++ /* Hit top of 'user' hierarchy */
++ break;
++ }
++ r = mboxlist_lookup(nbuf, NULL, NULL);
++ } while(r == IMAP_MAILBOX_NONEXISTENT);
+
+ syslog(LOG_NOTICE, "Deleted mailbox %s", mailbox->name);
+ mailbox_close(mailbox);
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/mboxlist.c cyrus-imapd-2.3-2.3.7/imap/mboxlist.c
+--- cyrus-imapd-2.3-2.3.7~/imap/mboxlist.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/mboxlist.c 2006-09-27 18:53:16.000000000 +0200
+@@ -40,7 +40,7 @@
+ *
+ */
+ /*
+- * $Id: mboxlist.c,v 1.221.2.22 2006/05/22 20:37:25 murch Exp $
++ * $Id: mboxlist.c,v 1.221.2.24 2006/08/10 18:20:53 murch Exp $
+ */
+
+ #include <config.h>
+@@ -2694,7 +2694,7 @@
+
+ void mboxlist_open(char *fname)
+ {
+- int ret;
++ int ret, flags;
+ char *tofree = NULL;
+
+ /* create db file name */
+@@ -2708,7 +2708,12 @@
+ strlcat(fname, FNAME_MBOXLIST, fname_len);
+ }
+
+- ret = DB->open(fname, CYRUSDB_CREATE, &mbdb);
++ flags = CYRUSDB_CREATE;
++ if (config_getswitch(IMAPOPT_IMPROVED_MBOXLIST_SORT)) {
++ flags |= CYRUSDB_MBOXSORT;
++ }
++
++ ret = DB->open(fname, flags, &mbdb);
+ if (ret != 0) {
+ syslog(LOG_ERR, "DBERROR: opening %s: %s", fname,
+ cyrusdb_strerror(ret));
+@@ -2776,12 +2781,18 @@
+ mboxlist_opensubs(const char *userid,
+ struct db **ret)
+ {
+- int r = 0;
++ int r = 0,flags;
+ char *subsfname;
+
+ /* Build subscription list filename */
+ subsfname = mboxlist_hash_usersubs(userid);
+- r = SUBDB->open(subsfname, CYRUSDB_CREATE, ret);
++
++ flags = CYRUSDB_CREATE;
++ if (config_getswitch(IMAPOPT_IMPROVED_MBOXLIST_SORT)) {
++ flags |= CYRUSDB_MBOXSORT;
++ }
++
++ r = SUBDB->open(subsfname, flags, ret);
+ if (r != CYRUSDB_OK) {
+ r = IMAP_IOERROR;
+ }
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/protocol.c cyrus-imapd-2.3-2.3.7/imap/protocol.c
+--- cyrus-imapd-2.3-2.3.7~/imap/protocol.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/protocol.c 2006-09-27 18:53:16.000000000 +0200
+@@ -39,7 +39,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: protocol.c,v 1.2.2.13 2006/06/27 15:58:42 murch Exp $ */
++/* $Id: protocol.c,v 1.2.2.14 2006/08/02 15:16:20 murch Exp $ */
+
+ #include <config.h>
+
+@@ -114,6 +114,7 @@
+ { " MUPDATE", CAPA_MUPDATE },
+ { " MULTIAPPEND", CAPA_MULTIAPPEND },
+ { " LIST-SUBSCRIBED", CAPA_LISTSUBSCRIBED },
++ { " RIGHTS=kxte", CAPA_ACLRIGHTS },
+ { NULL, 0 } } },
+ { "S01 STARTTLS", "S01 OK", "S01 NO" },
+ { "A01 AUTHENTICATE", 0, 0, "A01 OK", "A01 NO", "+ ", "*", NULL },
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/protocol.h cyrus-imapd-2.3-2.3.7/imap/protocol.h
+--- cyrus-imapd-2.3-2.3.7~/imap/protocol.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/protocol.h 2006-09-27 18:53:16.000000000 +0200
+@@ -39,7 +39,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: protocol.h,v 1.2.2.6 2006/06/27 15:58:42 murch Exp $ */
++/* $Id: protocol.h,v 1.2.2.7 2006/08/02 15:16:20 murch Exp $ */
+
+ #ifndef _INCLUDED_PROTOCOL_H
+ #define _INCLUDED_PROTOCOL_H
+@@ -56,13 +56,14 @@
+ CAPA_MUPDATE = (1 << 3),
+ CAPA_MULTIAPPEND = (1 << 4),
+ CAPA_LISTSUBSCRIBED = (1 << 5),
++ CAPA_ACLRIGHTS = (1 << 6),
+
+ /* LMTP capabilities */
+ CAPA_PIPELINING = (1 << 2),
+ CAPA_IGNOREQUOTA = (1 << 3)
+ };
+
+-#define MAX_CAPA 6
++#define MAX_CAPA 7
+
+ struct capa_t {
+ const char *str;
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/squatter.c cyrus-imapd-2.3-2.3.7/imap/squatter.c
+--- cyrus-imapd-2.3-2.3.7~/imap/squatter.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/squatter.c 2006-09-27 18:53:16.000000000 +0200
+@@ -37,7 +37,7 @@
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+- * $Id: squatter.c,v 1.12.2.5 2006/03/31 19:22:28 murch Exp $
++ * $Id: squatter.c,v 1.12.2.6 2006/09/26 16:49:41 murch Exp $
+ */
+
+ /*
+@@ -301,6 +301,22 @@
+ char uid_validity_buf[30];
+ char extname[MAX_MAILBOX_NAME+1];
+ int use_annot = *((int *) rock);
++ int mbtype;
++
++ /* Convert internal name to external */
++ (*squat_namespace.mboxname_toexternal)(&squat_namespace, name,
++ NULL, extname);
++
++ /* Skip remote mailboxes */
++ r = mboxlist_detail(name, &mbtype, NULL, NULL, NULL, NULL, NULL);
++ if (r) {
++ if (verbose) {
++ printf("error opening looking up %s: %s\n",
++ extname, error_message(r));
++ }
++ return 1;
++ }
++ if (mbtype & MBTYPE_REMOTE) return 0;
+
+ /* make sure the mailbox (or an ancestor) has
+ /vendor/cmu/cyrus-imapd/squat set to "true" */
+@@ -340,10 +356,6 @@
+ return 0;
+ }
+
+- /* Convert internal name to external */
+- (*squat_namespace.mboxname_toexternal)(&squat_namespace, name,
+- NULL, extname);
+-
+ data.mailbox_stats = &stats;
+ data.mailbox = &m;
+
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_client.c cyrus-imapd-2.3-2.3.7/imap/sync_client.c
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_client.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_client.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_client.c,v 1.1.2.35 2006/06/14 18:03:24 murch Exp $
++ * $Id: sync_client.c,v 1.1.2.38 2006/09/07 12:08:00 murch Exp $
+ */
+
+ #include <config.h>
+@@ -629,7 +629,7 @@
+ }
+
+ static int folder_create(char *name, char *part, char *uniqueid, char *acl,
+- unsigned long uidvalidity)
++ unsigned long options, unsigned long uidvalidity)
+ {
+ prot_printf(toserver, "CREATE ");
+ sync_printastring(toserver, name);
+@@ -639,10 +639,7 @@
+ sync_printastring(toserver, uniqueid);
+ prot_printf(toserver, " ");
+ sync_printastring(toserver, acl);
+- prot_printf(toserver, " ");
+- prot_printf(toserver, "0");
+- prot_printf(toserver, " ");
+- prot_printf(toserver, "%lu\r\n", uidvalidity);
++ prot_printf(toserver, " %d %lu %lu\r\n", 0, options, uidvalidity);
+ prot_flush(toserver);
+
+ return(sync_parse_code("CREATE", fromserver, SYNC_PARSE_EAT_OKLINE, NULL));
+@@ -1119,7 +1116,7 @@
+
+ /* Protocol for PARSED items:
+ * C: PARSED <msgid> <uid>
+- * <internaldate> <sent-date> <last-updated> <flags>
++ * <internaldate> <sent-date> <last-updated> <modseq> <flags>
+ * <hdr size> <content_lines>
+ * <cache literal (includes cache size!)>
+ * <msg literal (includes msg size!)>
+@@ -1127,7 +1124,7 @@
+
+ /* Protocol for COPY items:
+ * C: COPY <msgid> <uid>
+- * <internaldate> <sent-date> <last-updated> <flags>
++ * <internaldate> <sent-date> <last-updated> <modseq> <flags>
+ */
+
+ if (sync_msgid_lookup(msgid_onserver, &record->uuid)) {
+@@ -1139,10 +1136,10 @@
+ need_body = 1;
+ }
+
+- prot_printf(toserver, " %s %lu %lu %lu %lu (",
++ prot_printf(toserver, " %s %lu %lu %lu %lu " MODSEQ_FMT " (",
+ message_uuid_text(&record->uuid),
+ record->uid, record->internaldate,
+- record->sentdate, record->last_updated);
++ record->sentdate, record->last_updated, record->modseq);
+
+ flags_printed = 0;
+
+@@ -1190,8 +1187,8 @@
+ (char *)(mailbox->cache_base + record->cache_offset),
+ cache_size);
+
+- prot_printf(toserver, "{%lu+}\r\n", record->size);
+- prot_write(toserver, (char *)msg_base, record->size);
++ prot_printf(toserver, "{%lu+}\r\n", msg_size);
++ prot_write(toserver, (char *)msg_base, msg_size);
+ mailbox_unmap_message(mailbox, record->uid, &msg_base, &msg_size);
+ sequence++;
+ }
+@@ -1800,7 +1797,8 @@
+ goto bail;
+
+ if ((r=mboxlist_detail(m.name,NULL,NULL,NULL,&part,NULL,NULL))
+- || (r=folder_create(m.name,part,m.uniqueid,m.acl,m.uidvalidity)))
++ || (r=folder_create(m.name,part,m.uniqueid,m.acl,m.options,
++ m.uidvalidity)))
+ goto bail;
+
+ if (!r && m.quota.root && !strcmp(m.name, m.quota.root))
+@@ -1821,6 +1819,14 @@
+ if (!(folder2->acl && !strcmp(m.acl, folder2->acl)))
+ r = folder_setacl(folder->name, m.acl);
+
++ if ((folder2->options ^ m.options) & OPT_IMAP_CONDSTORE) {
++ r = folder_setannotation(m.name,
++ "/vendor/cmu/cyrus-imapd/condstore",
++ "",
++ (m.options & OPT_IMAP_CONDSTORE) ?
++ "true" : "false");
++ }
++
+ if (!r && m.quota.root && !strcmp(m.name, m.quota.root))
+ r = update_quota_work(&m.quota, &folder2->quota);
+
+@@ -1834,7 +1840,8 @@
+
+ /* Need to create fresh folder on server */
+ if ((r=mboxlist_detail(m.name,NULL,NULL,NULL,&part,NULL,NULL)) ||
+- (r=folder_create(m.name,part,m.uniqueid,m.acl,m.uidvalidity)))
++ (r=folder_create(m.name,part,m.uniqueid,m.acl,m.options,
++ m.uidvalidity)))
+ goto bail;
+
+ if (!r && m.quota.root && !strcmp(m.name, m.quota.root))
+@@ -1887,6 +1894,7 @@
+ static struct buf acl;
+ static struct buf name;
+ static struct buf lastuid;
++ static struct buf options;
+ static struct buf arg;
+ struct quota quota, *quotap;
+
+@@ -1918,7 +1926,10 @@
+ if ((c = getastring(fromserver, toserver, &acl)) != ' ')
+ goto parse_err;
+
+- c = getastring(fromserver, toserver, &lastuid);
++ if ((c = getastring(fromserver, toserver, &lastuid)) != ' ')
++ goto parse_err;
++
++ c = getastring(fromserver, toserver, &options);
+
+ quotap = NULL;
+ if (c == ' ') {
+@@ -1932,7 +1943,7 @@
+ if (!imparse_isnumber(lastuid.s)) goto parse_err;
+
+ folder = sync_folder_list_add(server_list, id.s, name.s, acl.s,
+- quotap);
++ sync_atoul(options.s), quotap);
+ folder->msglist = sync_msg_list_create(NULL, sync_atoul(lastuid.s));
+ break;
+ case 1:
+@@ -2021,7 +2032,7 @@
+ {
+ struct sync_folder_list *list = (struct sync_folder_list *) rock;
+
+- sync_folder_list_add(list, NULL, name, NULL, NULL);
++ sync_folder_list_add(list, NULL, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -2032,7 +2043,7 @@
+ {
+ struct sync_folder_list *list = (struct sync_folder_list *) rock;
+
+- sync_folder_list_add(list, name, name, NULL, NULL);
++ sync_folder_list_add(list, name, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -2310,6 +2321,7 @@
+ static struct buf flag;
+ static struct buf acl;
+ static struct buf lastuid;
++ static struct buf options;
+ static struct buf arg;
+ struct sync_folder *folder = NULL;
+ struct sync_msg *msg = NULL;
+@@ -2346,7 +2358,7 @@
+ c = getastring(fromserver, toserver, &name);
+ if (c == '\r') c = prot_getc(fromserver);
+ if (c != '\n') goto parse_err;
+- sync_folder_list_add(server_sub_list, name.s, name.s, NULL, NULL);
++ sync_folder_list_add(server_sub_list, name.s, name.s, NULL, 0, NULL);
+ break;
+ case 2:
+ /* New folder */
+@@ -2359,7 +2371,10 @@
+ if ((c = getastring(fromserver, toserver, &acl)) != ' ')
+ goto parse_err;
+
+- c = getastring(fromserver, toserver, &lastuid);
++ if ((c = getastring(fromserver, toserver, &lastuid)) != ' ')
++ goto parse_err;
++
++ c = getastring(fromserver, toserver, &options);
+
+ quotap = NULL;
+ if (c == ' ') {
+@@ -2373,7 +2388,7 @@
+ if (!imparse_isnumber(lastuid.s)) goto parse_err;
+
+ folder = sync_folder_list_add(server_list, id.s, name.s, acl.s,
+- quotap);
++ sync_atoul(options.s), quotap);
+ folder->msglist = sync_msg_list_create(NULL, sync_atoul(lastuid.s));
+ break;
+ case 1:
+@@ -2558,7 +2573,7 @@
+ r = IMAP_PROTOCOL_ERROR;
+ break;
+ }
+- sync_folder_list_add(server_list, name.s, name.s, NULL, NULL);
++ sync_folder_list_add(server_list, name.s, name.s, NULL, 0, NULL);
+
+ r = sync_parse_code("LSUB", fromserver,
+ SYNC_PARSE_EAT_OKLINE, &unsolicited);
+@@ -2967,7 +2982,7 @@
+ if (!action->active)
+ continue;
+
+- sync_folder_list_add(folder_list, NULL, action->name, NULL, NULL);
++ sync_folder_list_add(folder_list, NULL, action->name, NULL, 0, NULL);
+ }
+
+ if (folder_list->count) {
+@@ -3467,12 +3482,12 @@
+
+ if (!sync_folder_lookup_byname(folder_list, argv[i]))
+ sync_folder_list_add(folder_list,
+- NULL, argv[i], NULL, NULL);
++ NULL, argv[i], NULL, 0, NULL);
+ }
+ fclose(file);
+ } else for (i = optind; i < argc; i++) {
+ if (!sync_folder_lookup_byname(folder_list, argv[i]))
+- sync_folder_list_add(folder_list, NULL, argv[i], NULL, NULL);
++ sync_folder_list_add(folder_list, NULL, argv[i], NULL, 0, NULL);
+ }
+
+ if ((r = send_lock())) {
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_commit.c cyrus-imapd-2.3-2.3.7/imap/sync_commit.c
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_commit.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_commit.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_commit.c,v 1.1.2.10 2006/06/13 17:24:40 murch Exp $
++ * $Id: sync_commit.c,v 1.1.2.12 2006/07/11 14:36:24 murch Exp $
+ */
+
+ #include <config.h>
+@@ -108,6 +108,7 @@
+ struct index_record record;
+ int n, r = 0, rc;
+ struct txn *tid = NULL;
++ modseq_t highestmodseq = 0;
+
+ if (upload_list->count == 0) return(0); /* NOOP */
+
+@@ -233,6 +234,17 @@
+ = htonl(message->cache_version);
+
+ message_uuid_pack(&item->uuid, buf+OFFSET_MESSAGE_UUID);
++
++#ifdef HAVE_LONG_LONG_INT
++ *((bit64 *)(buf+OFFSET_MODSEQ_64)) = htonll(item->modseq);
++#else
++ /* zero the unused 32bits */
++ *((bit32 *)(buf+OFFSET_MODSEQ_64)) = htonl(0);
++ *((bit32 *)(buf+OFFSET_MODSEQ)) = htonl(item->modseq);
++#endif
++
++ if (item->modseq > highestmodseq) highestmodseq = item->modseq;
++
+ quota_add += message->msg_size;
+
+ if (item->flags.system_flags & FLAG_ANSWERED) numansweredflag++;
+@@ -297,6 +309,18 @@
+ /* Fix up last_append time */
+ *((bit32 *)(buf+OFFSET_LAST_APPENDDATE)) = htonl(last_appenddate);
+
++ /* Fix up highest modseq */
++#ifdef HAVE_LONG_LONG_INT
++ if (highestmodseq > *((bit64 *)(buf+OFFSET_HIGHESTMODSEQ_64))) {
++ *((bit64 *)(buf+OFFSET_HIGHESTMODSEQ_64)) = htonll(highestmodseq);
++ }
++#else
++ if (highestmodseq > *((bit32 *)(buf+OFFSET_HIGHESTMODSEQ))) {
++ *((bit32 *)(buf+OFFSET_HIGHESTMODSEQ_64)) = htonl(0);
++ *((bit32 *)(buf+OFFSET_HIGHESTMODSEQ)) = htonl(highestmodseq);
++ }
++#endif
++
+ rewind(newindex);
+ fwrite(buf, 1, mailbox->start_offset, newindex);
+
+@@ -451,6 +475,7 @@
+ char target[MAX_MAILBOX_PATH];
+ int n, r = 0;
+ struct txn *tid = NULL;
++ modseq_t highestmodseq = 0;
+
+ if (upload_list->count == 0) return(0); /* NOOP */
+
+@@ -493,6 +518,16 @@
+ = htonl(message->cache_version);
+ message_uuid_pack(&item->uuid, record+OFFSET_MESSAGE_UUID);
+
++#ifdef HAVE_LONG_LONG_INT
++ *((bit64 *)(record+OFFSET_MODSEQ_64)) = htonll(item->modseq);
++#else
++ /* zero the unused 32bits */
++ *((bit32 *)(record+OFFSET_MODSEQ_64)) = htonl(0);
++ *((bit32 *)(record+OFFSET_MODSEQ)) = htonl(item->modseq);
++#endif
++
++ if (item->modseq > highestmodseq) highestmodseq = item->modseq;
++
+ cache_size += message->cache_size;
+ quota_add += message->msg_size;
+
+@@ -579,6 +614,18 @@
+ /* Fix up last_append time */
+ *((bit32 *)(hbuf+OFFSET_LAST_APPENDDATE)) = htonl(last_appenddate);
+
++ /* Fix up highest modseq */
++#ifdef HAVE_LONG_LONG_INT
++ if (highestmodseq > ntohll(*((bit64 *)(hbuf+OFFSET_HIGHESTMODSEQ_64)))) {
++ *((bit64 *)(hbuf+OFFSET_HIGHESTMODSEQ_64)) = htonll(highestmodseq);
++ }
++#else
++ if (highestmodseq > ntohl(*((bit32 *)(hbuf+OFFSET_HIGHESTMODSEQ)))) {
++ *((bit32 *)(hbuf+OFFSET_HIGHESTMODSEQ_64)) = htonl(0);
++ *((bit32 *)(hbuf+OFFSET_HIGHESTMODSEQ)) = htonl(highestmodseq);
++ }
++#endif
++
+ /* And write it back out */
+ lseek(mailbox->index_fd, 0L, SEEK_SET);
+
+@@ -820,7 +867,7 @@
+
+ int
+ sync_create_commit(char *name, char *partition, char *uniqueid, char *acl,
+- int mbtype, unsigned long uidvalidity,
++ int mbtype, unsigned long options, unsigned long uidvalidity,
+ int isadmin, char *userid, struct auth_state *auth_state)
+ {
+ int r;
+@@ -904,13 +951,16 @@
+ if (mboxent) free(mboxent);
+ if (newpartition) free(newpartition);
+
+- /* Fix UIDvalidity */
++ /* Fix options and UIDvalidity */
+ if (!r) r = mailbox_open_header(name, 0, &m);
+ if (!r) mboxopen = 1;
+ if (!r) r = mailbox_lock_header(&m);
+ if (!r) r = mailbox_open_index(&m);
+ if (!r) r = mailbox_lock_index(&m);
+- if (!r) m.uidvalidity = uidvalidity;
++ if (!r) {
++ m.options = options;
++ m.uidvalidity = uidvalidity;
++ }
+ if (!r) mailbox_write_index_header(&m);
+
+ if (mboxopen) mailbox_close(&m);
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_commit.h cyrus-imapd-2.3-2.3.7/imap/sync_commit.h
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_commit.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_commit.h 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_commit.h,v 1.1.2.2 2005/05/17 18:29:46 ken3 Exp $
++ * $Id: sync_commit.h,v 1.1.2.3 2006/07/11 14:36:24 murch Exp $
+ */
+
+ #ifndef INCLUDED_SYNC_COMMIT_H
+@@ -58,7 +58,7 @@
+ struct sync_flag_list *flag_list);
+
+ int sync_create_commit(char *name, char *partition, char *uniqueid, char *acl,
+- int mbtype, unsigned long uidvalidity,
++ int mbtype, unsigned long options, unsigned long uidvalidity,
+ int isadmin, char *userid, struct auth_state *auth_state);
+
+ #endif /* INCLUDED_SYNC_COMMIT_H */
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_reset.c cyrus-imapd-2.3-2.3.7/imap/sync_reset.c
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_reset.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_reset.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_reset.c,v 1.1.2.4 2005/12/13 15:31:10 murch Exp $
++ * $Id: sync_reset.c,v 1.1.2.6 2006/08/02 21:26:43 murch Exp $
+ */
+
+ #include <config.h>
+@@ -124,6 +124,10 @@
+ if (sync_authstate) auth_freestate(sync_authstate);
+
+ seen_done();
++
++ quotadb_close();
++ quotadb_done();
++
+ mboxlist_close();
+ mboxlist_done();
+ exit(code);
+@@ -179,7 +183,7 @@
+
+ /* List all mailboxes, including directories and deleted items */
+
+- sync_folder_list_add(list, name, name, NULL, NULL);
++ sync_folder_list_add(list, name, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -191,7 +195,7 @@
+ {
+ struct sync_folder_list *list = (struct sync_folder_list *) rock;
+
+- sync_folder_list_add(list, name, name, NULL, NULL);
++ sync_folder_list_add(list, name, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -351,9 +355,13 @@
+ fatal(error_message(r), EC_CONFIG);
+ }
+
+- /* open the mboxlist, we'll need it for real work */
++ /* open the mboxlist and quotadb, we'll need them for real work */
+ mboxlist_init(0);
+ mboxlist_open(NULL);
++
++ quotadb_init(0);
++ quotadb_open(NULL);
++
+ mailbox_initialize();
+
+ signals_set_shutdown(&shut_down);
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_server.c cyrus-imapd-2.3-2.3.7/imap/sync_server.c
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_server.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_server.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_server.c,v 1.1.2.23 2006/06/12 18:56:42 murch Exp $
++ * $Id: sync_server.c,v 1.1.2.25 2006/07/11 14:36:24 murch Exp $
+ */
+
+ #include <config.h>
+@@ -169,7 +169,8 @@
+ static void cmd_user(char *userid);
+ static void cmd_create(char *mailboxname, char *partition,
+ char *uniqueid, char *acl,
+- int mbtype, unsigned long uidvalidity);
++ int mbtype, unsigned long options,
++ unsigned long uidvalidity);
+ static void cmd_delete(char *name);
+ static void cmd_rename(char *oldmailboxname, char *newmailboxname);
+ static void cmd_lsub(char *user);
+@@ -568,7 +569,7 @@
+ struct mailbox *mailbox = NULL;
+ struct sync_lock sync_lock;
+ static struct buf cmd;
+- static struct buf arg1, arg2, arg3, arg4, arg5, arg6;
++ static struct buf arg1, arg2, arg3, arg4, arg5, arg6, arg7;
+ int c;
+ char *p;
+
+@@ -672,14 +673,18 @@
+ c = getastring(sync_in, sync_out, &arg5);
+ if (c != ' ') goto missingargs;
+ c = getastring(sync_in, sync_out, &arg6);
++ if (c != ' ') goto missingargs;
++ c = getastring(sync_in, sync_out, &arg7);
+ if (c == '\r') c = prot_getc(sync_in);
+ if (c != '\n') goto extraargs;
+
+- if (!imparse_isnumber(arg5.s) || !imparse_isnumber(arg6.s))
++ if (!imparse_isnumber(arg5.s) || !imparse_isnumber(arg6.s) ||
++ !imparse_isnumber(arg7.s))
+ goto invalidargs;
+
+ cmd_create(arg1.s, arg2.s, arg3.s, arg4.s,
+- atoi(arg5.s), sync_atoul(arg6.s));
++ atoi(arg5.s), sync_atoul(arg6.s),
++ sync_atoul(arg7.s));
+ continue;
+ }
+ break;
+@@ -1526,7 +1531,7 @@
+
+ /* List all mailboxes, including directories and deleted items */
+
+- sync_folder_list_add(list, name, name, NULL, NULL);
++ sync_folder_list_add(list, name, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -1537,7 +1542,7 @@
+ {
+ struct sync_folder_list *list = (struct sync_folder_list *) rock;
+
+- sync_folder_list_add(list, name, name, NULL, NULL);
++ sync_folder_list_add(list, name, name, NULL, 0, NULL);
+ return(0);
+ }
+
+@@ -1838,6 +1843,17 @@
+ goto parse_err;
+ }
+
++ /* Parse modseq */
++ if ((c = getastring(sync_in, sync_out, &arg)) != ' ') {
++ err = "Invalid modseq";
++ goto parse_err;
++ }
++#ifdef HAVE_LONG_LONG_INT
++ item->modseq = sync_atoull(arg.s);
++#else
++ item->modseq = sync_atoul(arg.s);
++#endif
++
+ /* Parse Flags */
+ c = sync_getflags(sync_in, &item->flags, &upload_list->meta);
+
+@@ -2281,6 +2297,7 @@
+ prot_printf(sync_out, " ");
+ sync_printastring(sync_out, m.acl);
+ prot_printf(sync_out, " %lu", m.last_uid);
++ prot_printf(sync_out, " %lu", m.options);
+ if (m.quota.root && !strcmp(name, m.quota.root) &&
+ !quota_read(&m.quota, NULL, 0)) {
+ prot_printf(sync_out, " %d", m.quota.limit);
+@@ -2465,7 +2482,8 @@
+
+ static void cmd_create(char *mailboxname, char *partition,
+ char *uniqueid, char *acl,
+- int mbtype, unsigned long uidvalidity)
++ int mbtype, unsigned long options,
++ unsigned long uidvalidity)
+ {
+ int r;
+ char buf[MAX_MAILBOX_PATH+1];
+@@ -2492,7 +2510,7 @@
+ }
+
+ r = sync_create_commit(mailboxname, partition,
+- uniqueid, acl, mbtype, uidvalidity,
++ uniqueid, acl, mbtype, options, uidvalidity,
+ 1, sync_userid, sync_authstate);
+
+ if (r)
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_support.c cyrus-imapd-2.3-2.3.7/imap/sync_support.c
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_support.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_support.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_support.c,v 1.1.2.19 2006/06/14 18:03:24 murch Exp $
++ * $Id: sync_support.c,v 1.1.2.20 2006/07/11 14:36:25 murch Exp $
+ */
+
+ #include <config.h>
+@@ -559,6 +559,7 @@
+
+ struct sync_folder *sync_folder_list_add(struct sync_folder_list *l,
+ char *id, char *name, char *acl,
++ unsigned long options,
+ struct quota *quota)
+ {
+ struct sync_folder *result = xzmalloc(sizeof(struct sync_folder));
+@@ -575,6 +576,7 @@
+ result->id = (id) ? xstrdup(id) : NULL;
+ result->name = (name) ? xstrdup(name) : NULL;
+ result->acl = (acl) ? xstrdup(acl) : NULL;
++ result->options = options;
+ if (quota) {
+ result->quota.root = result->name;
+ result->quota.limit = quota->limit;
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/sync_support.h cyrus-imapd-2.3-2.3.7/imap/sync_support.h
+--- cyrus-imapd-2.3-2.3.7~/imap/sync_support.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/sync_support.h 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ * Original version written by David Carter <dpc22 at cam.ac.uk>
+ * Rewritten and integrated into Cyrus by Ken Murchison <ken at oceana.com>
+ *
+- * $Id: sync_support.h,v 1.1.2.9 2005/06/16 00:02:10 ken3 Exp $
++ * $Id: sync_support.h,v 1.1.2.11 2006/07/11 14:36:25 murch Exp $
+ */
+
+ #ifndef INCLUDED_SYNC_SUPPORT_H
+@@ -54,6 +54,7 @@
+ #define SYNC_MESSAGE_LIST_MAX_OPEN_FILES (64)
+
+ #define sync_atoul(s) strtoul(s, NULL, 10)
++#define sync_atoull(s) strtoull(s, NULL, 10)
+
+ int sync_eatlines_unsolicited(struct protstream *pin, int c);
+
+@@ -156,6 +157,7 @@
+ char *id;
+ char *name;
+ char *acl;
++ unsigned options;
+ struct quota quota;
+ int mark;
+ int reserve; /* Folder has been processed by reserve operation */
+@@ -171,6 +173,7 @@
+
+ struct sync_folder *sync_folder_list_add(struct sync_folder_list *l,
+ char *id, char *name, char *acl,
++ unsigned long options,
+ struct quota *quota);
+
+ struct sync_folder *sync_folder_lookup(struct sync_folder_list *l, char *id);
+@@ -323,6 +326,7 @@
+ time_t last_updated;
+ struct sync_flags flags;
+ struct message_uuid uuid;
++ modseq_t modseq;
+ struct sync_message *message;
+ };
+
+diff -urNad cyrus-imapd-2.3-2.3.7~/imap/tls.c cyrus-imapd-2.3-2.3.7/imap/tls.c
+--- cyrus-imapd-2.3-2.3.7~/imap/tls.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imap/tls.c 2006-09-27 18:53:16.000000000 +0200
+@@ -93,7 +93,7 @@
+ *
+ */
+
+-/* $Id: tls.c,v 1.47.2.3 2005/10/28 14:51:18 ken3 Exp $ */
++/* $Id: tls.c,v 1.47.2.4 2006/09/27 11:55:35 murch Exp $ */
+
+ #include <config.h>
+
+@@ -226,7 +226,7 @@
+ int err;
+ int depth;
+
+- syslog(LOG_ERR,"Doing a peer verify");
++ syslog(LOG_DEBUG, "Doing a peer verify");
+
+ err_cert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+diff -urNad cyrus-imapd-2.3-2.3.7~/imtest/imtest.c cyrus-imapd-2.3-2.3.7/imtest/imtest.c
+--- cyrus-imapd-2.3-2.3.7~/imtest/imtest.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/imtest/imtest.c 2006-09-27 18:53:16.000000000 +0200
+@@ -1,7 +1,7 @@
+ /* imtest.c -- IMAP/POP3/NNTP/LMTP/SMTP/MUPDATE/MANAGESIEVE test client
+ * Ken Murchison (multi-protocol implementation)
+ * Tim Martin (SASL implementation)
+- * $Id: imtest.c,v 1.93.2.15 2006/05/25 15:21:49 murch Exp $
++ * $Id: imtest.c,v 1.93.2.16 2006/08/30 16:32:24 murch Exp $
+ *
+ * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
+ *
+@@ -1083,7 +1083,8 @@
+
+ /* send to server */
+ if (sendliteral) {
+- printf("{%d+}\r\n", inbase64len);
++ printf("%s{%d+}\r\n",
++ initial_response ? "" : "C: ", inbase64len);
+ prot_printf(pout, "{%d+}\r\n", inbase64len);
+ prot_flush(pout);
+ }
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/acl.c cyrus-imapd-2.3-2.3.7/lib/acl.c
+--- cyrus-imapd-2.3-2.3.7~/lib/acl.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/acl.c 2006-09-27 18:53:16.000000000 +0200
+@@ -1,5 +1,5 @@
+ /* acl.c -- routines for access control lists
+- $Id: acl.c,v 1.10.4.1 2005/12/13 19:36:10 murch Exp $
++ $Id: acl.c,v 1.10.4.2 2006/08/17 16:14:03 murch Exp $
+
+ * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
+ *
+@@ -41,6 +41,8 @@
+ *
+ * Author: Chris Newman
+ * Start Date: 6/28/93
++ *
++ * RFC 4314 support added by Ken Murchison
+ */
+
+ #include <config.h>
+@@ -53,12 +55,11 @@
+ int cyrus_acl_strtomask(const char *str)
+ {
+ const char *deleteright = libcyrus_config_getstring(CYRUSOPT_DELETERIGHT);
++ long legacy_create = 0;
++ long legacy_delete = 0;
+ long result = 0;
+
+ while (*str) {
+- /* legacy DELETE right */
+- if (*str == *deleteright) result |= ACL_DELETEMBOX;
+-
+ switch (*str++) {
+ case 'l': result |= ACL_LOOKUP; break;
+ case 'r': result |= ACL_READ; break;
+@@ -66,13 +67,18 @@
+ case 'w': result |= ACL_WRITE; break;
+ case 'i': result |= ACL_INSERT; break;
+ case 'p': result |= ACL_POST; break;
+- case 'c': /* legacy CREATE macro */
++ case 'c': /* legacy CREATE macro - build member rights */
++ legacy_create = ACL_CREATE;
++ if (*deleteright == 'c') legacy_create |= ACL_DELETEMBOX;
++ break;
+ case 'k': result |= ACL_CREATE; break;
+ case 'x': result |= ACL_DELETEMBOX; break;
+ case 't': result |= ACL_DELETEMSG; break;
+ case 'e': result |= ACL_EXPUNGE; break;
+- case 'd': /* legacy DELETE macro */
+- result |= (ACL_DELETEMSG | ACL_EXPUNGE); break;
++ case 'd': /* legacy DELETE macro - build member rights */
++ legacy_delete = (ACL_DELETEMSG | ACL_EXPUNGE);
++ if (*deleteright == 'd') legacy_delete |= ACL_DELETEMBOX;
++ break;
+ case 'a': result |= ACL_ADMIN; break;
+ case '0': result |= ACL_USER0; break;
+ case '1': result |= ACL_USER1; break;
+@@ -87,32 +93,30 @@
+ }
+ }
+
++ /* If the rights string contained a legacy macro, but none of its
++ member rights, then we add all of the member rights for the macro.
++ Otherwise, we ignore the legacy macro.
++ */
++ if (!(result & legacy_create)) result |= legacy_create;
++ if (!(result & legacy_delete)) result |= legacy_delete;
++
+ return (result);
+ }
+
+ /* convert an acl bit vector to a string
+- *
+- * The 'legacy' parameter is used to control whether we return
+- * the legacy c/d macros when any of their member rights are set.
+- * 'legacy' is enabled (1) for GETACL/LISTRIGHTS/MYRIGHTS responses
+- * and disabled (0) for SETACL (when writing rights to disk).
+ */
+-char *cyrus_acl_masktostr(int acl, char *str, int legacy)
++char *cyrus_acl_masktostr(int acl, char *str)
+ {
+ char *pos = str;
+- int legacy_create = 0, legacy_delete = 0;
+-
+- if (legacy) {
+ const char *deleteright = libcyrus_config_getstring(CYRUSOPT_DELETERIGHT);
+- legacy_create = ACL_CREATE;
+- legacy_delete = (ACL_DELETEMSG | ACL_EXPUNGE);
++ int legacy_create = ACL_CREATE;
++ int legacy_delete = (ACL_DELETEMSG | ACL_EXPUNGE);
+
+ switch (*deleteright) {
+ case 'c': legacy_create |= ACL_DELETEMBOX; break;
+ case 'd': legacy_delete |= ACL_DELETEMBOX; break;
+ default: /* XXX we have backwards compatibility problems */ break;
+ }
+- }
+
+ if (acl & ACL_LOOKUP) *pos++ = 'l';
+ if (acl & ACL_READ) *pos++ = 'r';
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/acl.h cyrus-imapd-2.3-2.3.7/lib/acl.h
+--- cyrus-imapd-2.3-2.3.7~/lib/acl.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/acl.h 2006-09-27 18:53:16.000000000 +0200
+@@ -42,7 +42,7 @@
+ * Start Date: 6/28/93
+ */
+
+-/* $Id: acl.h,v 1.14.4.2 2006/05/18 18:04:52 murch Exp $ */
++/* $Id: acl.h,v 1.14.4.3 2006/08/17 16:14:03 murch Exp $ */
+
+ #ifndef INCLUDED_ACL_H
+ #define INCLUDED_ACL_H
+@@ -93,7 +93,7 @@
+ * dst must have room for 32 characters (only 20 used currently)
+ * returns dst
+ */
+-extern char *cyrus_acl_masktostr(int acl, char *str, int legacy);
++extern char *cyrus_acl_masktostr(int acl, char *str);
+
+ /* cyrus_acl_myrights(acl)
+ * Calculate the set of rights the user in 'auth_state' has in the ACL 'acl'.
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/acl_afs.c cyrus-imapd-2.3-2.3.7/lib/acl_afs.c
+--- cyrus-imapd-2.3-2.3.7~/lib/acl_afs.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/acl_afs.c 2006-09-27 18:53:16.000000000 +0200
+@@ -8,7 +8,7 @@
+ *
+ */
+ /*
+- $Id: acl_afs.c,v 1.22.4.3 2006/04/13 18:33:22 murch Exp $
++ $Id: acl_afs.c,v 1.22.4.4 2006/08/17 16:14:03 murch Exp $
+
+ * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
+ *
+@@ -206,7 +206,7 @@
+ strncpy(newacl, *acl, (thisid - *acl));
+ strcpy(newacl + (thisid - *acl), identifier);
+ strcat(newacl, "\t");
+- (void) cyrus_acl_masktostr(access, newacl + strlen(newacl), 0);
++ (void) cyrus_acl_masktostr(access, newacl + strlen(newacl));
+ strcat(newacl, "\t");
+ strcat(newacl, nextid);
+ free(*acl);
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/bsearch.c cyrus-imapd-2.3-2.3.7/lib/bsearch.c
+--- cyrus-imapd-2.3-2.3.7~/lib/bsearch.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/bsearch.c 2006-09-27 18:53:16.000000000 +0200
+@@ -1,5 +1,5 @@
+ /* bsearch.c -- binary search newline-separated fields in memory
+- $Id: bsearch.c,v 1.19 2003/02/13 20:15:39 rjs3 Exp $
++ $Id: bsearch.c,v 1.19.4.1 2006/08/01 19:34:18 murch Exp $
+
+ * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
+ *
+@@ -213,3 +213,22 @@
+ s2++;
+ }
+ }
++
++int bsearch_ncompare(const char *s1, int l1, const char *s2, int l2)
++{
++ int min = l1 < l2 ? l1 : l2;
++ int cmp = 0;
++
++ while (min-- > 0 && (cmp = TOCOMPARE(*s1) - TOCOMPARE(*s2)) == 0) {
++ s1++;
++ s2++;
++ }
++ if (min >= 0) {
++ return cmp;
++ } else {
++ if (l2 > l1) return -1;
++ else if (l1 > l2) return 1;
++ else return 0;
++ }
++}
++
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/bsearch.h cyrus-imapd-2.3-2.3.7/lib/bsearch.h
+--- cyrus-imapd-2.3-2.3.7~/lib/bsearch.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/bsearch.h 2006-09-27 18:53:16.000000000 +0200
+@@ -1,5 +1,5 @@
+ /* bsearch.h -- binary search
+- $Id: bsearch.h,v 1.7 2003/02/13 20:15:39 rjs3 Exp $
++ $Id: bsearch.h,v 1.7.4.1 2006/08/01 19:34:18 murch Exp $
+
+ * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
+ *
+@@ -51,4 +51,6 @@
+
+ extern int bsearch_compare(const char *s1, const char *s2);
+
++extern int bsearch_ncompare(const char *s1, int l1, const char *s2, int l2);
++
+ #endif /* INCLUDED_BSEARCH_H */
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/cyrusdb.h cyrus-imapd-2.3-2.3.7/lib/cyrusdb.h
+--- cyrus-imapd-2.3-2.3.7~/lib/cyrusdb.h 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/cyrusdb.h 2006-09-27 18:53:16.000000000 +0200
+@@ -38,7 +38,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: cyrusdb.h,v 1.25.2.4 2006/01/04 02:14:14 murch Exp $ */
++/* $Id: cyrusdb.h,v 1.25.2.5 2006/08/01 19:34:18 murch Exp $ */
+
+ #ifndef INCLUDED_CYRUSDB_H
+ #define INCLUDED_CYRUSDB_H
+@@ -67,7 +67,8 @@
+ };
+
+ enum cyrusdb_openflags {
+- CYRUSDB_CREATE = 0x01 /* Create the database if not existant */
++ CYRUSDB_CREATE = 0x01, /* Create the database if not existant */
++ CYRUSDB_MBOXSORT = 0x02 /* Use mailbox sort order ('.' sorts 1st) */
+ };
+
+ typedef int foreach_p(void *rock,
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/cyrusdb_berkeley.c cyrus-imapd-2.3-2.3.7/lib/cyrusdb_berkeley.c
+--- cyrus-imapd-2.3-2.3.7~/lib/cyrusdb_berkeley.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/cyrusdb_berkeley.c 2006-09-27 18:53:16.000000000 +0200
+@@ -39,7 +39,7 @@
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: cyrusdb_berkeley.c,v 1.2.2.12 2006/02/28 12:58:07 murch Exp $ */
++/* $Id: cyrusdb_berkeley.c,v 1.2.2.13 2006/08/01 19:34:18 murch Exp $ */
+
+ #include <config.h>
+
+@@ -51,6 +51,7 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+
++#include "bsearch.h"
+ #include "cyrusdb.h"
+ #include "exitcodes.h"
+ #include "libcyr_cfg.h"
+@@ -376,6 +377,12 @@
+ return 0;
+ }
+
++static int mbox_compar(DB *db, const DBT *a, const DBT *b)
++{
++ return bsearch_ncompare((const char *) a->data, a->size,
++ (const char *) b->data, b->size);
++}
++
+ static int myopen(const char *fname, DBTYPE type, int flags, struct db **ret)
+ {
+ DB *db = NULL;
+@@ -392,6 +399,7 @@
+ return CYRUSDB_IOERROR;
+ }
+ /* xxx set comparator! */
++ if (flags & CYRUSDB_MBOXSORT) db->set_bt_compare(db, mbox_compar);
+
+ #if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
+ r = db->open(db, NULL, fname, NULL, type, dbflags | DB_AUTO_COMMIT, 0664);
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/cyrusdb_skiplist.c cyrus-imapd-2.3-2.3.7/lib/cyrusdb_skiplist.c
+--- cyrus-imapd-2.3-2.3.7~/lib/cyrusdb_skiplist.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/cyrusdb_skiplist.c 2006-09-27 18:53:16.000000000 +0200
+@@ -1,5 +1,5 @@
+ /* cyrusdb_skiplist.c -- cyrusdb skiplist implementation
+- * $Id: cyrusdb_skiplist.c,v 1.42.2.3 2004/06/09 19:42:47 ken3 Exp $
++ * $Id: cyrusdb_skiplist.c,v 1.42.2.4 2006/08/01 19:34:18 murch Exp $
+ *
+ * Copyright (c) 1998, 2000, 2002 Carnegie Mellon University.
+ * All rights reserved.
+@@ -61,6 +61,7 @@
+ #endif
+ #include <netinet/in.h>
+
++#include "bsearch.h"
+ #include "cyrusdb.h"
+ #include "libcyr_cfg.h"
+ #include "lock.h"
+@@ -153,6 +154,9 @@
+ int listsize;
+ int logstart; /* where the log starts from last chkpnt */
+ time_t last_recovery;
++
++ /* comparator function to use for sorting */
++ int (*compar) (const char *s1, int l1, const char *s2, int l2);
+ };
+
+ struct txn {
+@@ -175,6 +179,8 @@
+ use_osync = 0
+ };
+
++static int compare(const char *s1, int l1, const char *s2, int l2);
++
+ static void newtxn(struct db *db, struct txn *t)
+ {
+ /* fill in t */
+@@ -674,6 +680,7 @@
+
+ db->fd = -1;
+ db->fname = xstrdup(fname);
++ db->compar = (flags & CYRUSDB_MBOXSORT) ? bsearch_ncompare : compare;
+
+ db->fd = open(fname, O_RDWR, 0644);
+ if (db->fd == -1 && errno == ENOENT && (flags & CYRUSDB_CREATE)) {
+@@ -824,7 +831,7 @@
+
+ for (i = db->curlevel - 1; i >= 0; i--) {
+ while ((offset = FORWARD(ptr, i)) &&
+- compare(KEY(db->map_base + offset), KEYLEN(db->map_base + offset),
++ db->compar(KEY(db->map_base + offset), KEYLEN(db->map_base + offset),
+ key, keylen) < 0) {
+ /* move forward at level 'i' */
+ ptr = db->map_base + offset;
+@@ -875,7 +882,7 @@
+
+ ptr = find_node(db, key, keylen, 0);
+
+- if (ptr == db->map_base || compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ if (ptr == db->map_base || db->compar(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+ /* failed to find key/keylen */
+ r = CYRUSDB_NOTFOUND;
+ } else {
+@@ -963,7 +970,7 @@
+ while (ptr != db->map_base) {
+ /* does it match prefix? */
+ if (KEYLEN(ptr) < (bit32) prefixlen) break;
+- if (prefixlen && compare(KEY(ptr), prefixlen, prefix, prefixlen)) break;
++ if (prefixlen && db->compar(KEY(ptr), prefixlen, prefix, prefixlen)) break;
+
+ if (!goodp ||
+ goodp(rock, KEY(ptr), KEYLEN(ptr), DATA(ptr), DATALEN(ptr))) {
+@@ -1116,7 +1123,7 @@
+ newoffset = tp->logend;
+ ptr = find_node(db, key, keylen, updateoffsets);
+ if (ptr != db->map_base &&
+- !compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ !db->compar(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+
+ if (!overwrite) {
+ myabort(db, tp); /* releases lock */
+@@ -1282,7 +1289,7 @@
+
+ ptr = find_node(db, key, keylen, updateoffsets);
+ if (ptr == db->map_base ||
+- !compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ !db->compar(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+ /* gotcha */
+ offset = ptr - db->map_base;
+
+@@ -1825,11 +1832,11 @@
+ const char *q = db->map_base + offset;
+ int cmp;
+
+- cmp = compare(KEY(ptr), KEYLEN(ptr), KEY(q), KEYLEN(q));
++ cmp = db->compar(KEY(ptr), KEYLEN(ptr), KEY(q), KEYLEN(q));
+ if (cmp >= 0) {
+ fprintf(stdout,
+ "skiplist inconsistent: %04X: ptr %d is %04X; "
+- "compare() = %d\n",
++ "db->compar() = %d\n",
+ ptr - db->map_base,
+ i,
+ offset, cmp);
+@@ -2058,7 +2065,7 @@
+ if (TYPE(ptr) == ADD) {
+ keyptr = find_node(db, KEY(ptr), KEYLEN(ptr), updateoffsets);
+ if (keyptr == db->map_base ||
+- compare(KEY(ptr), KEYLEN(ptr), KEY(keyptr), KEYLEN(keyptr))) {
++ db->compar(KEY(ptr), KEYLEN(ptr), KEY(keyptr), KEYLEN(keyptr))) {
+ /* didn't find exactly this node */
+ keyptr = NULL;
+ }
+diff -urNad cyrus-imapd-2.3-2.3.7~/lib/imapoptions cyrus-imapd-2.3-2.3.7/lib/imapoptions
+--- cyrus-imapd-2.3-2.3.7~/lib/imapoptions 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/lib/imapoptions 2006-09-27 18:53:16.000000000 +0200
+@@ -42,7 +42,7 @@
+ .\" AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ .\"
+-.\" $Id: imapoptions,v 1.2.2.47 2006/06/27 15:58:42 murch Exp $
++.\" $Id: imapoptions,v 1.2.2.48 2006/08/10 18:20:53 murch Exp $
+ .SH NAME
+ imapd.conf \- IMAP configuration file
+ .SH DESCRIPTION
+@@ -300,6 +300,14 @@
+ configuration. If the path to the file is not absolute, CYRUS_PATH
+ is prepended. */
+
++{ "improved_mboxlist_sort", 0, SWITCH }
++/* If enabled, a special comparator will be used which will correctly
++ sort mailbox names that contain characters such as ' ' and '-'.
++.PP
++ Note that this option SHOULD NOT be changed on a live system.
++ The mailboxes database should be dumped before the option is changed,
++ removed, and then undumped after changing the option. */
++
+ { "ldap_authz", NULL, STRING }
+ /* SASL authorization ID for the LDAP server */
+
+diff -urNad cyrus-imapd-2.3-2.3.7~/ptclient/ldap.c cyrus-imapd-2.3-2.3.7/ptclient/ldap.c
+--- cyrus-imapd-2.3-2.3.7~/ptclient/ldap.c 2006-08-26 02:00:13.000000000 +0200
++++ cyrus-imapd-2.3-2.3.7/ptclient/ldap.c 2006-09-27 18:53:16.000000000 +0200
+@@ -41,7 +41,7 @@
+ */
+
+ static char rcsid[] __attribute__((unused)) =
+- "$Id: ldap.c,v 1.2.2.7 2006/04/13 18:39:44 murch Exp $";
++ "$Id: ldap.c,v 1.2.2.8 2006/09/11 13:55:27 murch Exp $";
+
+ #include <config.h>
+ #include "ptloader.h"
+@@ -1064,7 +1064,6 @@
+ if (vals == NULL)
+ continue;
+
+- strcpy((*newstate)->groups[i].id, "group:");
+ int j;
+ strcpy((*newstate)->groups[i].id, "group:");
+ for(j =0; j < strlen(vals[i]); j++) {
Propchange: branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/0001-upstream-update-to-post-2-3-7-cvs-head.dpatch
------------------------------------------------------------------------------
svn:executable = *
Modified: branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/00list
URL: https://mail.incase.de/viewcvs/branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/00list?rev=639&root=cyrus22&r1=638&r2=639&view=diff
==============================================================================
--- branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/00list (original)
+++ branches/cyrus23-farzy/cyrus-imapd-2.3-2.3.7/debian/patches/00list Tue Oct 3 15:14:19 2006
@@ -1,3 +1,4 @@
+0001-upstream-update-to-post-2-3-7-cvs-head.dpatch
01-fix_Makefile.in.dpatch
02-add_mkinstalldirs.dpatch
03-fix_docs.dpatch
More information about the Pkg-Cyrus-imapd-Debian-devel
mailing list