|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/ctl_cyrusdb.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/ctl_cyrusdb.c 2007-03-30 21:40:20.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c 2007-08-21 16:49:06.000000000 +0300
|
|
|
cf58a5c |
@@ -133,7 +133,7 @@
|
|
|
d0d307a |
/* if it is MBTYPE_RESERVED, unset it & call mboxlist_delete */
|
|
|
d0d307a |
if(!r && (mbtype & MBTYPE_RESERVE)) {
|
|
|
d0d307a |
if(!r) {
|
|
|
d0d307a |
- r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1);
|
|
|
d0d307a |
+ r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1, 1);
|
|
|
d0d307a |
if(r) {
|
|
|
d0d307a |
/* log the error */
|
|
|
d0d307a |
syslog(LOG_ERR,
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/ctl_mboxlist.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/ctl_mboxlist.c 2007-07-18 21:56:11.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
@@ -484,7 +484,7 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
wipe_head = wipe_head->next;
|
|
|
d0d307a |
|
|
|
d0d307a |
- ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1);
|
|
|
d0d307a |
+ ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1, 1);
|
|
Tomas Janousek |
915c4a4 |
if(!ret) sync_log_mailbox(me->mailbox);
|
|
|
d0d307a |
if(ret) {
|
|
|
d0d307a |
fprintf(stderr, "couldn't delete defunct mailbox %s\n",
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/imapd.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/imapd.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/imapd.c 2007-08-02 17:18:51.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/imapd.c 2007-08-21 16:49:28.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
@@ -4994,7 +4994,7 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
r = mboxlist_deletemailbox(name, imapd_userisadmin,
|
|
|
d0d307a |
imapd_userid, imapd_authstate,
|
|
|
d0d307a |
- 0, 0, 0);
|
|
|
d0d307a |
+ 0, 0, 0, 1);
|
|
|
d0d307a |
|
|
|
cf58a5c |
if (!r) sync_log_mailbox(name);
|
|
|
cf58a5c |
|
|
Tomas Janousek |
14dc340 |
@@ -5018,6 +5018,12 @@
|
|
|
d0d307a |
char *p;
|
|
|
d0d307a |
int domainlen = 0;
|
|
|
cf58a5c |
int sync_lockfd = (-1);
|
|
|
d0d307a |
+ int keepQuota = 1;
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ if(name && *name == '+') {
|
|
Tomas Janousek |
915c4a4 |
+ keepQuota = 0;
|
|
Tomas Janousek |
915c4a4 |
+ name++;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
|
|
|
d0d307a |
r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name,
|
|
|
d0d307a |
imapd_userid, mailboxname);
|
|
Tomas Janousek |
14dc340 |
@@ -5076,7 +5082,7 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
r = mboxlist_deletemailbox(mailboxname, imapd_userisadmin,
|
|
|
cf58a5c |
imapd_userid, imapd_authstate, 1-force,
|
|
|
d0d307a |
- localonly, 0);
|
|
|
d0d307a |
+ localonly, 0, keepQuota);
|
|
|
d0d307a |
}
|
|
|
d0d307a |
|
|
|
d0d307a |
/* was it a top-level user mailbox? */
|
|
Tomas Janousek |
14dc340 |
@@ -6434,6 +6440,7 @@
|
|
|
d0d307a |
{
|
|
|
d0d307a |
int newquota = -1;
|
|
|
d0d307a |
int badresource = 0;
|
|
|
d0d307a |
+ int rmquota = 0;
|
|
|
d0d307a |
int c;
|
|
|
d0d307a |
int force = 0;
|
|
|
d0d307a |
static struct buf arg;
|
|
Tomas Janousek |
14dc340 |
@@ -6450,7 +6457,8 @@
|
|
|
d0d307a |
if (c != ')' || arg.s[0] != '\0') {
|
|
|
d0d307a |
for (;;) {
|
|
|
d0d307a |
if (c != ' ') goto badlist;
|
|
|
d0d307a |
- if (strcasecmp(arg.s, "storage") != 0) badresource = 1;
|
|
|
d0d307a |
+ if (strcasecmp(arg.s, "remove") == 0) rmquota = 1;
|
|
|
d0d307a |
+ else if (strcasecmp(arg.s, "storage") != 0) badresource = 1;
|
|
|
d0d307a |
c = getword(imapd_in, &arg;;
|
|
|
d0d307a |
if (c != ' ' && c != ')') goto badlist;
|
|
|
d0d307a |
if (arg.s[0] == '\0') goto badlist;
|
|
Tomas Janousek |
14dc340 |
@@ -6519,7 +6527,10 @@
|
|
Tomas Janousek |
915c4a4 |
|
|
Tomas Janousek |
915c4a4 |
/* local mailbox */
|
|
Tomas Janousek |
915c4a4 |
if (!r || (r == IMAP_MAILBOX_NONEXISTENT)) {
|
|
|
cf58a5c |
- r = mboxlist_setquota(mailboxname, newquota, force);
|
|
Tomas Janousek |
915c4a4 |
+ if(!rmquota)
|
|
|
cf58a5c |
+ r = mboxlist_setquota(mailboxname, newquota, force);
|
|
Tomas Janousek |
915c4a4 |
+ else
|
|
|
cf58a5c |
+ r = mboxlist_unsetquota(mailboxname);
|
|
|
d0d307a |
}
|
|
|
d0d307a |
|
|
|
cf58a5c |
imapd_check(NULL, 0, 0);
|
|
Tomas Janousek |
14dc340 |
@@ -8237,7 +8248,7 @@
|
|
Tomas Janousek |
14dc340 |
/* note also that we need to remember to let proxyadmins do this */
|
|
Tomas Janousek |
14dc340 |
r = mboxlist_deletemailbox(mailboxname,
|
|
Tomas Janousek |
14dc340 |
imapd_userisadmin || imapd_userisproxyadmin,
|
|
Tomas Janousek |
14dc340 |
- imapd_userid, imapd_authstate, 0, 1, 0);
|
|
Tomas Janousek |
14dc340 |
+ imapd_userid, imapd_authstate, 0, 1, 0, 1);
|
|
Tomas Janousek |
14dc340 |
if(r) syslog(LOG_ERR,
|
|
Tomas Janousek |
14dc340 |
"Could not delete local mailbox during move of %s",
|
|
Tomas Janousek |
14dc340 |
mailboxname);
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/mailbox.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mailbox.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/mailbox.c 2007-07-20 17:21:57.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mailbox.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -2745,27 +2745,7 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
seen_delete_mailbox(mailbox);
|
|
|
d0d307a |
|
|
|
d0d307a |
- if (delete_quota_root && !rquota) {
|
|
|
d0d307a |
- quota_delete(&mailbox->quota, &tid;;
|
|
|
d0d307a |
- free(mailbox->quota.root);
|
|
|
d0d307a |
- mailbox->quota.root = NULL;
|
|
|
d0d307a |
- } else if (!rquota) {
|
|
|
d0d307a |
- /* Free any quota being used by this mailbox */
|
|
|
d0d307a |
- if (mailbox->quota.used >= mailbox->quota_mailbox_used) {
|
|
|
d0d307a |
- mailbox->quota.used -= mailbox->quota_mailbox_used;
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
- else {
|
|
|
d0d307a |
- mailbox->quota.used = 0;
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
- r = quota_write(&mailbox->quota, &tid;;
|
|
|
d0d307a |
- if (r) {
|
|
|
d0d307a |
- syslog(LOG_ERR,
|
|
|
cf58a5c |
- "LOSTQUOTA: unable to record free of " UQUOTA_T_FMT " bytes in quota %s",
|
|
|
d0d307a |
- mailbox->quota_mailbox_used, mailbox->quota.root);
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
- else
|
|
|
d0d307a |
- quota_commit(&tid;;
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
+ mailbox_updatequota(mailbox,NULL);
|
|
|
d0d307a |
|
|
Tomas Janousek |
915c4a4 |
/* Flush data (message file) directory */
|
|
Tomas Janousek |
915c4a4 |
mailbox_delete_files(mailbox->path);
|
|
Tomas Janousek |
14dc340 |
@@ -3394,3 +3374,48 @@
|
|
|
d0d307a |
if (*p == '.') *p = '/';
|
|
|
d0d307a |
}
|
|
|
d0d307a |
}
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+/* This function is used to update the quota. Can be used to replace
|
|
Tomas Janousek |
915c4a4 |
+ * identical parts of the code, and can be quite handy some times
|
|
|
d0d307a |
+ * The tid is used in order to make possible to make the quota update
|
|
|
d0d307a |
+ * being a part of a bigger transaction to the quota db */
|
|
|
d0d307a |
+int mailbox_updatequota(struct mailbox *mailbox, struct txn **tid)
|
|
|
d0d307a |
+{
|
|
|
d0d307a |
+ int r = 0, havetid = 0;
|
|
|
d0d307a |
+ struct txn **ltid = NULL;
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ if(tid) {
|
|
|
d0d307a |
+ ltid = tid;
|
|
|
d0d307a |
+ havetid = 1;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ /* Ensure that we are locked */
|
|
|
d0d307a |
+ if(!mailbox->header_lock_count) return IMAP_INTERNAL;
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ if(mailbox->quota.root) {
|
|
|
d0d307a |
+ r = quota_read(&mailbox->quota, ltid, 1);
|
|
|
d0d307a |
+ if( r == 0 ) {
|
|
|
d0d307a |
+ if (mailbox->quota.used >= mailbox->quota_mailbox_used) {
|
|
|
d0d307a |
+ mailbox->quota.used -= mailbox->quota_mailbox_used;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ else {
|
|
|
d0d307a |
+ mailbox->quota.used = 0;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ r = quota_write(&mailbox->quota, ltid);
|
|
|
d0d307a |
+ if (r) {
|
|
|
d0d307a |
+ syslog(LOG_ERR,
|
|
|
d0d307a |
+ "LOSTQUOTA: unable to record free of %lu bytes in quota %s",
|
|
|
d0d307a |
+ mailbox->quota_mailbox_used, mailbox->quota.root);
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ else if(!havetid)
|
|
|
cf58a5c |
+ quota_commit(tid);
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ /* It is not a big mistake not to have quota .. just remove from the mailbox */
|
|
|
d0d307a |
+ else if ( r == IMAP_QUOTAROOT_NONEXISTENT) {
|
|
|
d0d307a |
+ free(mailbox->quota.root);
|
|
|
d0d307a |
+ r = 0;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ return r;
|
|
|
d0d307a |
+}
|
|
|
d0d307a |
+
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/mailbox.h cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mailbox.h
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/mailbox.h 2006-11-30 19:11:19.000000000 +0200
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mailbox.h 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -364,6 +364,8 @@
|
|
|
d0d307a |
struct mailbox *mailboxp);
|
|
|
d0d307a |
extern int mailbox_delete(struct mailbox *mailbox, int delete_quota_root);
|
|
|
d0d307a |
|
|
|
d0d307a |
+extern int mailbox_updatequota(struct mailbox *mailbox, struct txn **tid);
|
|
|
d0d307a |
+
|
|
|
d0d307a |
extern int mailbox_rename_copy(struct mailbox *oldmailbox,
|
|
|
cf58a5c |
const char *newname, char *newpartition,
|
|
|
d0d307a |
bit32 *olduidvalidityp, bit32 *newuidvalidityp,
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/mboxlist.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mboxlist.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/mboxlist.c 2007-08-15 20:20:55.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mboxlist.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -95,6 +95,12 @@
|
|
|
d0d307a |
static int mboxlist_opensubs();
|
|
|
d0d307a |
static void mboxlist_closesubs();
|
|
|
d0d307a |
|
|
|
d0d307a |
+static int child_cb(char *name,
|
|
|
d0d307a |
+ int matchlen __attribute__((unused)),
|
|
|
d0d307a |
+ int maycreate __attribute__((unused)),
|
|
|
d0d307a |
+ void *rock);
|
|
|
d0d307a |
+
|
|
Tomas Janousek |
915c4a4 |
+
|
|
|
d0d307a |
static int mboxlist_rmquota(const char *name, int matchlen, int maycreate,
|
|
|
d0d307a |
void *rock);
|
|
|
d0d307a |
static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
|
|
Tomas Janousek |
915c4a4 |
@@ -102,6 +108,7 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
struct change_rock {
|
|
|
d0d307a |
struct quota *quota;
|
|
|
d0d307a |
+ struct quota *oldquota;
|
|
|
d0d307a |
struct txn **tid;
|
|
|
d0d307a |
};
|
|
|
d0d307a |
|
|
Tomas Janousek |
915c4a4 |
@@ -889,9 +896,9 @@
|
|
|
d0d307a |
*/
|
|
|
d0d307a |
int mboxlist_deletemailbox(const char *name, int isadmin, char *userid,
|
|
|
d0d307a |
struct auth_state *auth_state, int checkacl,
|
|
|
d0d307a |
- int local_only, int force)
|
|
|
d0d307a |
+ int local_only, int force, int keepQuota)
|
|
|
d0d307a |
{
|
|
|
d0d307a |
- int r;
|
|
|
d0d307a |
+ int r, has_children = 0;
|
|
|
d0d307a |
char *acl;
|
|
|
d0d307a |
long access;
|
|
|
d0d307a |
struct mailbox mailbox;
|
|
Tomas Janousek |
915c4a4 |
@@ -902,6 +909,7 @@
|
|
|
cf58a5c |
int mbtype;
|
|
|
d0d307a |
const char *p;
|
|
|
d0d307a |
mupdate_handle *mupdate_h = NULL;
|
|
|
d0d307a |
+ char *quotaroot = NULL;
|
|
|
d0d307a |
|
|
|
d0d307a |
if(!isadmin && force) return IMAP_PERMISSION_DENIED;
|
|
|
d0d307a |
|
|
Tomas Janousek |
915c4a4 |
@@ -1014,15 +1022,47 @@
|
|
|
d0d307a |
|
|
|
d0d307a |
if ((r && !force) || isremote) goto done;
|
|
|
d0d307a |
|
|
|
d0d307a |
- if (!r || force) r = mailbox_delete(&mailbox, deletequotaroot);
|
|
|
d0d307a |
+ if (!r || force) {
|
|
|
d0d307a |
+ /* first we have to keep the previous quota root in order to delete it */
|
|
|
d0d307a |
+ if(mailbox.quota.root)
|
|
|
d0d307a |
+ quotaroot = xstrdup(mailbox.quota.root);
|
|
Tomas Janousek |
915c4a4 |
+ r = mailbox_delete(&mailbox, deletequotaroot);
|
|
|
d0d307a |
+ }
|
|
Tomas Janousek |
915c4a4 |
+
|
|
|
d0d307a |
|
|
|
d0d307a |
/*
|
|
|
d0d307a |
* See if we have to remove mailbox's quota root
|
|
|
d0d307a |
*/
|
|
|
d0d307a |
- if (!r && mailbox.quota.root != NULL) {
|
|
Tomas Janousek |
915c4a4 |
- /* xxx look for any other mailboxes in this quotaroot */
|
|
|
d0d307a |
+ if (!r && quotaroot != NULL) {
|
|
Tomas Janousek |
915c4a4 |
+ /* xxx look for any other mailboxes in this quotaroot */
|
|
Tomas Janousek |
915c4a4 |
+ /* If we have not asked to remove the quota (default behaviour), we check
|
|
|
d0d307a |
+ * whether there are any subfolders beneeth the quota root. If there aren't
|
|
|
d0d307a |
+ * any subfolders the reasonable thing is to delete the quota */
|
|
|
d0d307a |
+ if(keepQuota) {
|
|
|
d0d307a |
+ char pattern[MAX_MAILBOX_PATH+1];
|
|
|
d0d307a |
+ strlcpy(pattern, quotaroot, sizeof(pattern));
|
|
|
d0d307a |
+ if (config_virtdomains && name[strlen(name)-1] == '!') {
|
|
|
d0d307a |
+ strlcat(pattern, "*", sizeof(pattern));
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ else {
|
|
|
d0d307a |
+ strlcat(pattern, ".*", sizeof(pattern));
|
|
Tomas Janousek |
915c4a4 |
+ }
|
|
Tomas Janousek |
915c4a4 |
+ /* find if there are subfolders. Then we want to
|
|
Tomas Janousek |
915c4a4 |
+ * keep the existing quota */
|
|
|
d0d307a |
+ mboxlist_findall(NULL, pattern, isadmin, userid,
|
|
|
d0d307a |
+ auth_state, child_cb, (void *) &has_children);
|
|
|
d0d307a |
+
|
|
Tomas Janousek |
915c4a4 |
+ if(!has_children)
|
|
Tomas Janousek |
915c4a4 |
+ if(!mboxlist_mylookup(quotaroot, NULL, NULL, NULL, NULL, NULL, 0, 1))
|
|
Tomas Janousek |
915c4a4 |
+ has_children = 1;
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ /* If we want to remove the quota explicitely or the quota root folder has no subfolders
|
|
|
d0d307a |
+ * we execute the rmquota patch */
|
|
|
d0d307a |
+ if(!keepQuota || !has_children )
|
|
|
d0d307a |
+ mboxlist_unsetquota(quotaroot);
|
|
|
d0d307a |
+ free(quotaroot);
|
|
|
d0d307a |
}
|
|
Tomas Janousek |
915c4a4 |
-
|
|
Tomas Janousek |
915c4a4 |
+
|
|
|
d0d307a |
done:
|
|
Tomas Janousek |
915c4a4 |
if(r && tid && !force) {
|
|
Tomas Janousek |
915c4a4 |
/* Abort the transaction if it is still in progress */
|
|
Tomas Janousek |
915c4a4 |
@@ -2483,6 +2523,7 @@
|
|
|
d0d307a |
if (r) return r;
|
|
|
d0d307a |
|
|
|
d0d307a |
crock.quota = "a;
|
|
|
d0d307a |
+ crock.oldquota = NULL;
|
|
|
d0d307a |
crock.tid = &tid;
|
|
|
d0d307a |
/* top level mailbox */
|
|
|
d0d307a |
if(have_mailbox)
|
|
Tomas Janousek |
915c4a4 |
@@ -2501,15 +2542,19 @@
|
|
|
d0d307a |
*/
|
|
|
d0d307a |
int mboxlist_unsetquota(const char *root)
|
|
|
d0d307a |
{
|
|
|
d0d307a |
+ char newquota[MAX_MAILBOX_PATH+1];
|
|
|
d0d307a |
char pattern[MAX_MAILBOX_PATH+1];
|
|
|
d0d307a |
struct quota quota;
|
|
|
d0d307a |
- int r=0;
|
|
|
d0d307a |
+ struct change_rock crock;
|
|
|
d0d307a |
+ int r=0, k=0;
|
|
|
d0d307a |
|
|
|
d0d307a |
if (!root[0] || root[0] == '.' || strchr(root, '/')
|
|
|
d0d307a |
|| strchr(root, '*') || strchr(root, '%') || strchr(root, '?')) {
|
|
|
d0d307a |
return IMAP_MAILBOX_BADNAME;
|
|
|
d0d307a |
}
|
|
|
d0d307a |
|
|
Tomas Janousek |
915c4a4 |
+ crock.tid=NULL;
|
|
Tomas Janousek |
915c4a4 |
+
|
|
|
d0d307a |
quota.root = (char *) root;
|
|
Tomas Janousek |
915c4a4 |
r = quota_read("a, NULL, 0);
|
|
|
d0d307a |
if (r == IMAP_QUOTAROOT_NONEXISTENT) {
|
|
Tomas Janousek |
915c4a4 |
@@ -2534,9 +2579,47 @@
|
|
Tomas Janousek |
915c4a4 |
/* submailboxes - we're using internal names here */
|
|
Tomas Janousek |
915c4a4 |
mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_rmquota, (void *)root);
|
|
|
d0d307a |
|
|
|
d0d307a |
- r = quota_delete("a, NULL);
|
|
|
d0d307a |
+ r = quota_delete("a, crock.tid);
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ /* If we cannot delete the quota then abort the operation */
|
|
|
d0d307a |
+ if(!r) {
|
|
|
d0d307a |
+ /* quota_findroot performs several checks that we can
|
|
|
d0d307a |
+ * assume that are already done, and don't have to perform
|
|
|
d0d307a |
+ * them again. One of them is that it returns 1 only if
|
|
|
d0d307a |
+ * quotaroot exists.
|
|
|
d0d307a |
+ */
|
|
|
d0d307a |
+ if(quota_findroot(newquota, sizeof(newquota), root)) {
|
|
|
d0d307a |
+ struct quota rootquota;
|
|
|
d0d307a |
+ rootquota.root = newquota;
|
|
|
d0d307a |
+ k = quota_read(&rootquota, crock.tid, 0);
|
|
|
d0d307a |
+ if (!k) {
|
|
|
d0d307a |
+ crock.quota = &rootquota;
|
|
|
d0d307a |
+ crock.oldquota = "a;
|
|
|
d0d307a |
+ /* top level mailbox */
|
|
|
d0d307a |
+ k = mboxlist_changequota(root, 0, 0, &crock);
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ /* submailboxes - we're using internal names here */
|
|
|
d0d307a |
+ if (!k)
|
|
|
d0d307a |
+ k = mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_changequota, &crock);
|
|
|
d0d307a |
+ if(!k)
|
|
|
d0d307a |
+ k = quota_write(&rootquota, crock.tid);
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ else {
|
|
|
d0d307a |
+ /* top level mailbox */
|
|
|
d0d307a |
+ mboxlist_rmquota(root, 0, 0, (void *)root);
|
|
|
d0d307a |
+ /* submailboxes - we're using internal names here */
|
|
|
d0d307a |
+ mboxlist_findall(NULL, pattern, 1, 0, 0, mboxlist_rmquota, (void *)root);
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+ }
|
|
|
d0d307a |
+
|
|
|
d0d307a |
+ if(!r && !k)
|
|
|
d0d307a |
+ quota_commit(crock.tid);
|
|
|
d0d307a |
+ else
|
|
|
d0d307a |
+ quota_abort(crock.tid);
|
|
|
d0d307a |
|
|
|
d0d307a |
return r;
|
|
Tomas Janousek |
915c4a4 |
+
|
|
|
d0d307a |
}
|
|
Tomas Janousek |
915c4a4 |
|
|
Tomas Janousek |
915c4a4 |
/*
|
|
Tomas Janousek |
915c4a4 |
@@ -2632,6 +2715,7 @@
|
|
|
d0d307a |
struct mailbox mailbox;
|
|
|
d0d307a |
struct change_rock *crock = (struct change_rock *) rock;
|
|
|
d0d307a |
struct quota *mboxlist_newquota = crock->quota;
|
|
|
d0d307a |
+ struct quota *mboxlist_oldquota = crock->oldquota;
|
|
|
d0d307a |
struct txn **tid = crock->tid;
|
|
|
d0d307a |
|
|
|
d0d307a |
assert(rock != NULL);
|
|
Tomas Janousek |
915c4a4 |
@@ -2649,27 +2733,24 @@
|
|
|
d0d307a |
if (r) goto error;
|
|
|
d0d307a |
|
|
|
d0d307a |
if (mailbox.quota.root) {
|
|
|
d0d307a |
- if (strlen(mailbox.quota.root) >= strlen(mboxlist_newquota->root)) {
|
|
|
d0d307a |
- /* Part of a child quota root */
|
|
|
d0d307a |
- mailbox_close(&mailbox);
|
|
|
d0d307a |
- return 0;
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
-
|
|
|
d0d307a |
- r = quota_read(&mailbox.quota, tid, 1);
|
|
|
d0d307a |
- if (r) goto error;
|
|
|
d0d307a |
- if (mailbox.quota.used >= mailbox.quota_mailbox_used) {
|
|
|
d0d307a |
- mailbox.quota.used -= mailbox.quota_mailbox_used;
|
|
Tomas Janousek |
915c4a4 |
- }
|
|
Tomas Janousek |
915c4a4 |
- else {
|
|
|
d0d307a |
- mailbox.quota.used = 0;
|
|
|
d0d307a |
- }
|
|
|
d0d307a |
- r = quota_write(&mailbox.quota, tid);
|
|
|
d0d307a |
- if (r) {
|
|
|
d0d307a |
- syslog(LOG_ERR,
|
|
|
cf58a5c |
- "LOSTQUOTA: unable to record free of " UQUOTA_T_FMT " bytes in quota %s",
|
|
|
d0d307a |
- mailbox.quota_mailbox_used, mailbox.quota.root);
|
|
Tomas Janousek |
915c4a4 |
- }
|
|
|
d0d307a |
- free(mailbox.quota.root);
|
|
Tomas Janousek |
915c4a4 |
+ if(mboxlist_oldquota) {
|
|
Tomas Janousek |
915c4a4 |
+ if (strlen(mailbox.quota.root) > strlen(mboxlist_oldquota->root)) {
|
|
Tomas Janousek |
915c4a4 |
+ /* Part of a child quota root */
|
|
Tomas Janousek |
915c4a4 |
+ mailbox_close(&mailbox);
|
|
Tomas Janousek |
915c4a4 |
+ return 0;
|
|
Tomas Janousek |
915c4a4 |
+ }
|
|
Tomas Janousek |
915c4a4 |
+ }
|
|
Tomas Janousek |
915c4a4 |
+ else {
|
|
Tomas Janousek |
915c4a4 |
+ if (strlen(mailbox.quota.root) >= strlen(mboxlist_newquota->root)) {
|
|
Tomas Janousek |
915c4a4 |
+ /* Part of a child quota root */
|
|
Tomas Janousek |
915c4a4 |
+ mailbox_close(&mailbox);
|
|
Tomas Janousek |
915c4a4 |
+ return 0;
|
|
Tomas Janousek |
915c4a4 |
+ }
|
|
Tomas Janousek |
915c4a4 |
+ }
|
|
|
d0d307a |
+
|
|
Tomas Janousek |
915c4a4 |
+ r = mailbox_updatequota(&mailbox,tid);
|
|
Tomas Janousek |
915c4a4 |
+ if (r)
|
|
Tomas Janousek |
915c4a4 |
+ goto error;
|
|
|
d0d307a |
}
|
|
|
d0d307a |
|
|
|
d0d307a |
mailbox.quota.root = xstrdup(mboxlist_newquota->root);
|
|
Tomas Janousek |
915c4a4 |
@@ -2682,6 +2763,11 @@
|
|
Tomas Janousek |
915c4a4 |
|
|
|
d0d307a |
error:
|
|
|
d0d307a |
mailbox_close(&mailbox);
|
|
|
d0d307a |
+ syslog(LOG_ERR, "LOSTQUOTA: unable to change quota root for %s to %s: %s. \
|
|
|
d0d307a |
+ Command aborted. Run reconstruct to make sure mailboxes \
|
|
|
d0d307a |
+ are in consistent state",
|
|
|
d0d307a |
+ name, mboxlist_newquota->root, error_message(r));
|
|
|
d0d307a |
+ return 1;
|
|
|
d0d307a |
error_noclose:
|
|
|
d0d307a |
syslog(LOG_ERR, "LOSTQUOTA: unable to change quota root for %s to %s: %s",
|
|
Tomas Janousek |
915c4a4 |
name, mboxlist_newquota->root, error_message(r));
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/mboxlist.h cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mboxlist.h
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/mboxlist.h 2006-11-30 19:11:19.000000000 +0200
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/mboxlist.h 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -126,7 +126,7 @@
|
|
|
d0d307a |
* the planet */
|
|
|
d0d307a |
int mboxlist_deletemailbox(const char *name, int isadmin, char *userid,
|
|
|
d0d307a |
struct auth_state *auth_state, int checkacl,
|
|
|
d0d307a |
- int local_only, int force);
|
|
|
d0d307a |
+ int local_only, int force, int keepQuota);
|
|
|
d0d307a |
|
|
|
d0d307a |
/* Rename/move a mailbox (hierarchical) */
|
|
|
d0d307a |
int mboxlist_renamemailbox(char *oldname, char *newname, char *partition,
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/nntpd.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/nntpd.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/nntpd.c 2007-03-30 21:51:01.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/nntpd.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -3358,7 +3358,7 @@
|
|
|
d0d307a |
/* XXX should we delete right away, or wait until empty? */
|
|
|
d0d307a |
|
|
|
d0d307a |
r = mboxlist_deletemailbox(mailboxname, 0,
|
|
|
d0d307a |
- newsmaster, newsmaster_authstate, 1, 0, 0);
|
|
|
d0d307a |
+ newsmaster, newsmaster_authstate, 1, 0, 0, 1);
|
|
|
d0d307a |
|
|
|
cf58a5c |
if (!r) sync_log_mailbox(mailboxname);
|
|
|
cf58a5c |
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/sync_reset.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/sync_reset.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/sync_reset.c 2007-03-30 21:40:21.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/sync_reset.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
915c4a4 |
@@ -258,7 +258,7 @@
|
|
|
cf58a5c |
if (r) goto fail;
|
|
|
cf58a5c |
|
|
|
cf58a5c |
for (item = list->head ; item ; item = item->next) {
|
|
|
cf58a5c |
- r=mboxlist_deletemailbox(item->name, 1, NULL, sync_authstate, 1, 0, 0);
|
|
|
cf58a5c |
+ r=mboxlist_deletemailbox(item->name, 1, NULL, sync_authstate, 1, 0, 0, 1);
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if (r) goto fail;
|
|
|
cf58a5c |
}
|
|
Tomas Janousek |
915c4a4 |
@@ -274,7 +274,7 @@
|
|
|
cf58a5c |
if (r) goto fail;
|
|
|
cf58a5c |
|
|
|
cf58a5c |
for (item = list->head ; item ; item = item->next) {
|
|
|
cf58a5c |
- r=mboxlist_deletemailbox(item->name, 1, NULL, sync_authstate, 1, 0, 0);
|
|
|
cf58a5c |
+ r=mboxlist_deletemailbox(item->name, 1, NULL, sync_authstate, 1, 0, 0, 1);
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if (r) goto fail;
|
|
|
cf58a5c |
}
|
|
Tomas Janousek |
915c4a4 |
@@ -282,7 +282,7 @@
|
|
|
cf58a5c |
|
|
|
cf58a5c |
/* Nuke inbox (recursive nuke possible?) */
|
|
|
cf58a5c |
snprintf(buf, sizeof(buf)-1, "user.%s", user);
|
|
|
cf58a5c |
- r = mboxlist_deletemailbox(buf, 1, "cyrus", sync_authstate, 1, 0, 0);
|
|
|
cf58a5c |
+ r = mboxlist_deletemailbox(buf, 1, "cyrus", sync_authstate, 1, 0, 0, 1);
|
|
|
cf58a5c |
if (r && (r != IMAP_MAILBOX_NONEXISTENT)) goto fail;
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if ((r=user_deletedata(user, sync_userid, sync_authstate, 1)))
|
|
Tomas Janousek |
14dc340 |
diff -Naur cyrus-imapd-2.3.9/imap/sync_server.c cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/sync_server.c
|
|
Tomas Janousek |
14dc340 |
--- cyrus-imapd-2.3.9/imap/sync_server.c 2007-08-01 22:19:03.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
+++ cyrus-imapd-2.3.9-rmquota+deletemailbox.uncompiled/imap/sync_server.c 2007-08-21 16:49:06.000000000 +0300
|
|
Tomas Janousek |
14dc340 |
@@ -1590,7 +1590,7 @@
|
|
|
cf58a5c |
|
|
|
cf58a5c |
for (item = list->head ; item ; item = item->next) {
|
|
|
cf58a5c |
r=mboxlist_deletemailbox(item->name, sync_userisadmin, sync_userid,
|
|
|
cf58a5c |
- sync_authstate, 0, 0, 1);
|
|
|
cf58a5c |
+ sync_authstate, 0, 0, 1, 1);
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if (r) goto fail;
|
|
|
cf58a5c |
}
|
|
Tomas Janousek |
14dc340 |
@@ -1600,7 +1600,7 @@
|
|
|
cf58a5c |
(sync_namespacep->mboxname_tointernal)(sync_namespacep, "INBOX",
|
|
|
cf58a5c |
user, buf);
|
|
|
cf58a5c |
r = mboxlist_deletemailbox(buf, sync_userisadmin, sync_userid,
|
|
|
cf58a5c |
- sync_authstate, 0, 0, 1);
|
|
|
cf58a5c |
+ sync_authstate, 0, 0, 1, 1);
|
|
|
cf58a5c |
if (r && (r != IMAP_MAILBOX_NONEXISTENT)) goto fail;
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if ((r=user_deletedata(user, sync_userid, sync_authstate, 1)))
|
|
Tomas Janousek |
14dc340 |
@@ -2546,7 +2546,7 @@
|
|
|
cf58a5c |
|
|
|
cf58a5c |
/* Delete with admin priveleges */
|
|
|
cf58a5c |
r = mboxlist_deletemailbox(name, sync_userisadmin, sync_userid,
|
|
|
cf58a5c |
- sync_authstate, 0, 0, 1);
|
|
|
cf58a5c |
+ sync_authstate, 0, 0, 1, 1);
|
|
|
cf58a5c |
|
|
|
cf58a5c |
if (r)
|
|
|
cf58a5c |
prot_printf(sync_out, "NO Failed to delete %s: %s\r\n",
|