Index: cyrus-imapd-2.3.9/imap/mailbox.c =================================================================== --- cyrus-imapd-2.3.9.orig/imap/mailbox.c 2007-08-21 01:28:56.000000000 -0400 +++ cyrus-imapd-2.3.9/imap/mailbox.c 2007-08-21 01:36:23.000000000 -0400 @@ -3362,6 +3362,7 @@ { const char *idx; char c, *p; + char itemname[MAX_MAILBOX_PATH+1]; snprintf(buf, buf_len, "%s", root); buf_len -= strlen(buf); @@ -3369,7 +3370,7 @@ if (config_virtdomains && (p = strchr(name, '!'))) { *p = '\0'; /* split domain!user */ - if (config_hashimapspool) { + if (config_hashimapspool != IMAP_ENUM_HASHIMAPSPOOL_OFF) { c = (char) dir_hash_c(name, config_fulldirhash); snprintf(buf, buf_len, "%s%c/%s", FNAME_DOMAINDIR, c, name); } @@ -3382,7 +3383,7 @@ buf += strlen(buf); } - if (config_hashimapspool) { + if (config_hashimapspool == IMAP_ENUM_HASHIMAPSPOOL_ON) { idx = strchr(name, '.'); if (idx == NULL) { idx = name; @@ -3392,13 +3393,30 @@ c = (char) dir_hash_c(idx, config_fulldirhash); snprintf(buf, buf_len, "/%c/%s", c, name); + + /* change all '.'s to '/' */ + for (p = buf; *p; p++) { + if (*p == '.') *p = '/'; + } + } else if (config_hashimapspool == IMAP_ENUM_HASHIMAPSPOOL_USERID) { + if (idx = mboxname_isusermailbox(name, 0)) { + c = (char) dir_hash_c(idx, config_fulldirhash); + strncpy(itemname, idx, MAX_MAILBOX_PATH); + if (p = strchr(itemname, '.')) *p = '\0'; /* trim to username */ + snprintf(buf, buf_len, "/user/%c/%s/%s", c, itemname, name); + } else { + strncpy(itemname, name, MAX_MAILBOX_PATH); + if (p = strchr(itemname, '.')) *p = '\0'; /* trim to first part */ + snprintf(buf, buf_len, "/%s/%s", itemname, name); + } } else { /* standard mailbox placement */ snprintf(buf, buf_len, "/%s", name); - } - /* change all '.'s to '/' */ - for (p = buf; *p; p++) { - if (*p == '.') *p = '/'; + /* change all '.'s to '/' */ + for (p = buf; *p; p++) { + if (*p == '.') *p = '/'; + } } + } Index: cyrus-imapd-2.3.9/lib/imapoptions =================================================================== --- cyrus-imapd-2.3.9.orig/lib/imapoptions 2007-08-21 01:28:56.000000000 -0400 +++ cyrus-imapd-2.3.9/lib/imapoptions 2007-08-21 01:28:59.000000000 -0400 @@ -266,10 +266,14 @@ server must be quiesced and then the directories moved with the \fBrehash\fR utility. */ -{ "hashimapspool", 0, SWITCH } +{ "hashimapspool", "off", ENUM("off", "userid", "on") } /* If enabled, the partitions will also be hashed, in addition to the hashing done on configuration directories. This is recommended if - one partition has a very bushy mailbox tree. */ + one partition has a very bushy mailbox tree. +.PP + If set to "userid" then the second item will be stripped out as + the directory path and the other dots won't be converted: + e.g. /b/brong/user.brong.Trash/ */ # Commented out - there's no such thing as "hostname_mechs", but we need # this for the man page Index: cyrus-imapd-2.3.9/lib/libconfig.c =================================================================== --- cyrus-imapd-2.3.9.orig/lib/libconfig.c 2007-08-21 01:28:56.000000000 -0400 +++ cyrus-imapd-2.3.9/lib/libconfig.c 2007-08-21 01:28:59.000000000 -0400 @@ -74,7 +74,7 @@ const char *config_mupdate_server = NULL;/* NULL */ const char *config_defdomain = NULL; /* NULL */ const char *config_ident = NULL; /* the service name */ -int config_hashimapspool; /* f */ +enum enum_value config_hashimapspool; /* f */ enum enum_value config_virtdomains; /* f */ enum enum_value config_mupdate_config; /* IMAP_ENUM_MUPDATE_CONFIG_STANDARD */ @@ -274,7 +274,7 @@ } /* look up mailbox hashing */ - config_hashimapspool = config_getswitch(IMAPOPT_HASHIMAPSPOOL); + config_hashimapspool = config_getenum(IMAPOPT_HASHIMAPSPOOL); /* are we supporting virtual domains? */ config_virtdomains = config_getenum(IMAPOPT_VIRTDOMAINS); Index: cyrus-imapd-2.3.9/lib/libconfig.h =================================================================== --- cyrus-imapd-2.3.9.orig/lib/libconfig.h 2007-08-21 01:28:56.000000000 -0400 +++ cyrus-imapd-2.3.9/lib/libconfig.h 2007-08-21 01:28:59.000000000 -0400 @@ -71,7 +71,7 @@ extern const char *config_mupdate_server; extern const char *config_defdomain; extern const char *config_ident; -extern int config_hashimapspool; +extern enum enum_value config_hashimapspool; extern int config_implicitrights; extern enum enum_value config_virtdomains; extern enum enum_value config_mupdate_config;