[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 @@
+ 		       &copyuid, !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