Skip to content

Commit

Permalink
mboxlist.c: add 'U' field (user inboxid) to mbentry_t
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed Mar 12, 2024
1 parent 0c2ebac commit a02794d
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 31 deletions.
83 changes: 54 additions & 29 deletions imap/ctl_cyrusdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,17 @@ static void usage(void)
exit(-1);
}

struct fix_rock {
char *inboxname;
char *inboxid;
};

/* Callback for use by process_mboxlist */
static int fixmbox(const mbentry_t *mbentry,
void *rock __attribute__((unused)))
static int fixmbox(const mbentry_t *mbentry, void *rock)
{
struct fix_rock *frock = (struct fix_rock *) rock;
struct mailbox *mailbox = NULL;
mbentry_t *copy = NULL;
int r, r2;

/* if MBTYPE_RESERVED, unset it & call mboxlist_delete */
Expand Down Expand Up @@ -160,17 +167,12 @@ static int fixmbox(const mbentry_t *mbentry,
buf_free(&buf);
free(userid);
}
mbentry_t *copy = mboxlist_entry_copy(mbentry);
mbentry = copy = mboxlist_entry_copy(mbentry);
xzfree(copy->legacy_specialuse);
mboxlist_updatelock(copy, /*localonly*/1);
mboxlist_entry_free(&copy);
}

/* make sure every local mbentry has a uniqueid! */
if (!mbentry->uniqueid && mbentry_is_local_mailbox(mbentry)) {
struct mailbox *mailbox = NULL;
mbentry_t *copy = NULL;

r = mailbox_open_from_mbe(mbentry, &mailbox);
if (r) {
/* XXX what does it mean if there's an mbentry, but the mailbox
Expand All @@ -189,35 +191,55 @@ static int fixmbox(const mbentry_t *mbentry,
mbentry->name, mailbox->h.uniqueid);
}

copy = mboxlist_entry_copy(mbentry);
if (!copy) mbentry = copy = mboxlist_entry_copy(mbentry);
copy->uniqueid = xstrdup(mailbox->h.uniqueid);
xsyslog(LOG_INFO, "mbentry had no uniqueid, setting from header",
"mboxname=<%s> newuniqueid=<%s>",
copy->name, copy->uniqueid);

skip_uniqueid:
; /* hush "label at end of compound statement" warning */
}

if (mboxname_isusermailbox(mbentry->name, 1)) {
free(frock->inboxname);
free(frock->inboxid);
frock->inboxname = xstrdup(mbentry->name);
frock->inboxid = xstrdup(mbentry->uniqueid);
}
if (!mbentry->inboxid && frock->inboxname &&
mboxname_is_prefix(mbentry->name, frock->inboxname)) {
xsyslog(LOG_INFO, "mbentry had no inboxid, setting from",
"inboxname=<%s> inboxid=<%s>",
frock->inboxname, frock->inboxid);
if (!copy) mbentry = copy = mboxlist_entry_copy(mbentry);
copy->inboxid = xstrdup(frock->inboxid);
}

if (copy) {
r = mboxlist_updatelock(copy, /*localonly*/1);
if (r) {
xsyslog(LOG_ERR, "failed to update mboxlist",
"mboxname=<%s> error=<%s>",
mbentry->name, error_message(r));
r2 = mailbox_abort(mailbox);
if (r2) {
xsyslog(LOG_ERR, "DBERROR: error aborting transaction",
"error=<%s>", cyrusdb_strerror(r2));
mboxlist_entry_free(&copy);

if (mailbox) {
if (r) {
xsyslog(LOG_ERR, "failed to update mboxlist",
"mboxname=<%s> error=<%s>",
mbentry->name, error_message(r));
r2 = mailbox_abort(mailbox);
if (r2) {
xsyslog(LOG_ERR, "DBERROR: error aborting transaction",
"error=<%s>", cyrusdb_strerror(r2));
}
}
}
else {
r2 = mailbox_commit(mailbox);
if (r2) {
xsyslog(LOG_ERR, "DBERROR: error committing transaction",
"error=<%s>", cyrusdb_strerror(r2));
else {
r2 = mailbox_commit(mailbox);
if (r2) {
xsyslog(LOG_ERR, "DBERROR: error committing transaction",
"error=<%s>", cyrusdb_strerror(r2));
}
}
mailbox_close(&mailbox);
}
mailbox_close(&mailbox);
mboxlist_entry_free(&copy);

skip_uniqueid:
; /* hush "label at end of compound statement" warning */
}

return 0;
Expand All @@ -229,7 +251,10 @@ static void process_mboxlist(int *upgraded)
mboxlist_upgrade(upgraded);

/* run fixmbox across all mboxlist entries */
mboxlist_allmbox(NULL, fixmbox, NULL, MBOXTREE_INTERMEDIATES);
struct fix_rock frock = { 0 };
mboxlist_allmbox(NULL, fixmbox, &frock, MBOXTREE_INTERMEDIATES);
free(frock.inboxname);
free(frock.inboxid);

/* enable or disable RACLs per config */
mboxlist_set_racls(config_getswitch(IMAPOPT_REVERSEACLS));
Expand Down
5 changes: 5 additions & 0 deletions imap/mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,11 @@ EXPORTED const char *mailbox_uniqueid(const struct mailbox *mailbox)
return mbentry->uniqueid ? mbentry->uniqueid : mailbox->h.uniqueid;
}

EXPORTED const char *mailbox_inboxid(const struct mailbox *mailbox)
{
return mailbox->mbentry->inboxid;
}

EXPORTED const char *mailbox_partition(const struct mailbox *mailbox)
{
return mailbox->mbentry->partition;
Expand Down
1 change: 1 addition & 0 deletions imap/mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ extern int mailbox_delete(struct mailbox **mailboxptr);
/* reading details */
extern const char *mailbox_name(const struct mailbox *mailbox);
extern const char *mailbox_uniqueid(const struct mailbox *mailbox);
extern const char *mailbox_inboxid(const struct mailbox *mailbox);
extern const char *mailbox_partition(const struct mailbox *mailbox);
extern const char *mailbox_acl(const struct mailbox *mailbox);
extern const char *mailbox_quotaroot(const struct mailbox *mailbox);
Expand Down
19 changes: 18 additions & 1 deletion imap/mboxlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ EXPORTED mbentry_t *mboxlist_entry_copy(const mbentry_t *src)
copy->server = xstrdupnull(src->server);
copy->acl = xstrdupnull(src->acl);
copy->uniqueid = xstrdupnull(src->uniqueid);
copy->inboxid = xstrdupnull(src->inboxid);

copy->legacy_specialuse = xstrdupnull(src->legacy_specialuse);

Expand Down Expand Up @@ -187,6 +188,7 @@ EXPORTED void mboxlist_entry_free(mbentry_t **mbentryptr)
free(mbentry->server);
free(mbentry->acl);
free(mbentry->uniqueid);
free(mbentry->inboxid);

free(mbentry->legacy_specialuse);

Expand Down Expand Up @@ -273,6 +275,9 @@ static struct dlist *mboxlist_entry_dlist(const char *dbname,
else if (mbentry->uniqueid)
dlist_setatom(dl, "I", mbentry->uniqueid);

if (mbentry->inboxid)
dlist_setatom(dl, "U", mbentry->inboxid);

if (mbentry->partition)
dlist_setatom(dl, "P", mbentry->partition);

Expand Down Expand Up @@ -618,6 +623,9 @@ static int parseentry_cb(int type, struct dlistsax_data *d)
else if (!strcmp(key, "I")) {
rock->mbentry->uniqueid = xstrdupnull(d->data);
}
else if (!strcmp(key, "U")) {
rock->mbentry->inboxid = xstrdupnull(d->data);
}
else if (!strcmp(key, "M")) {
rock->mbentry->mtime = atoi(d->data);
}
Expand Down Expand Up @@ -652,6 +660,7 @@ static int parseentry_cb(int type, struct dlistsax_data *d)
* F: _f_oldermodseq
* H: name_h_istory
* I: unique_i_d
* U: _u_serinboxid
* M: _m_time
* N: _n_ame
* P: _p_artition
Expand Down Expand Up @@ -1865,6 +1874,7 @@ EXPORTED int mboxlist_createmailbox(const mbentry_t *mbentry,
int isremote = mbtype & MBTYPE_REMOTE;
mbentry_t *usermbentry = NULL, *newmbentry = NULL;
int silent = 0;
int isinbox;

init_internal();

Expand All @@ -1874,6 +1884,8 @@ EXPORTED int mboxlist_createmailbox(const mbentry_t *mbentry,

assert_namespacelocked(mboxname);

isinbox = mboxname_isusermailbox(mboxname, 1);

if ((flags & MBOXLIST_CREATE_SYNC)) {
silent = 1;
}
Expand Down Expand Up @@ -1933,9 +1945,11 @@ EXPORTED int mboxlist_createmailbox(const mbentry_t *mbentry,
newmbentry->mbtype = mbtype;
newmbentry->partition = xstrdupnull(newpartition);
newmbentry->uniqueid = xstrdup(uniqueid ? uniqueid : makeuuid());
if (isinbox) newmbentry->inboxid = xstrdup(newmbentry->uniqueid);
else if (usermbentry) newmbentry->inboxid = xstrdup(usermbentry->uniqueid);

if (!(flags & MBOXLIST_CREATE_DBONLY) && !isremote) {
if (mboxname_isusermailbox(mboxname, 1)) {
if (isinbox) {
/* Create initial mbentry for new users --
the uniqueid in the record is required to open
user metadata files (conversations, counters) */
Expand Down Expand Up @@ -2766,6 +2780,7 @@ EXPORTED int mboxlist_renamemailbox(const mbentry_t *mbentry,
newmbentry->acl = xstrdupnull(mailbox_acl(oldmailbox));
newmbentry->uidvalidity = oldmailbox->i.uidvalidity;
newmbentry->uniqueid = xstrdupnull(mailbox_uniqueid(oldmailbox));
newmbentry->inboxid = xstrdupnull(mailbox_inboxid(oldmailbox));
newmbentry->createdmodseq = oldmailbox->i.createdmodseq;
newmbentry->foldermodseq = silent ? mailbox_foldermodseq(oldmailbox)
: mboxname_nextmodseq(newname, mailbox_foldermodseq(oldmailbox),
Expand Down Expand Up @@ -2830,6 +2845,7 @@ EXPORTED int mboxlist_renamemailbox(const mbentry_t *mbentry,
newmbentry->acl = xstrdupnull(mailbox_acl(newmailbox));
newmbentry->uidvalidity = newmailbox->i.uidvalidity;
newmbentry->uniqueid = xstrdupnull(mailbox_uniqueid(newmailbox));
newmbentry->inboxid = xstrdupnull(mailbox_inboxid(newmailbox));
newmbentry->createdmodseq = newmailbox->i.createdmodseq;
newmbentry->foldermodseq = newmailbox->i.highestmodseq;
}
Expand All @@ -2842,6 +2858,7 @@ EXPORTED int mboxlist_renamemailbox(const mbentry_t *mbentry,
newmbentry->acl = xstrdupnull(mailbox_acl(oldmailbox));
newmbentry->uidvalidity = oldmailbox->i.uidvalidity;
newmbentry->uniqueid = xstrdupnull(mailbox_uniqueid(oldmailbox));
newmbentry->inboxid = xstrdupnull(mailbox_inboxid(oldmailbox));
newmbentry->createdmodseq = oldmailbox->i.createdmodseq;
newmbentry->foldermodseq = oldmailbox->i.highestmodseq;

Expand Down
3 changes: 2 additions & 1 deletion imap/mboxlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,15 @@ struct mboxlist_entry {
char *acl;
/* extra fields */
char *uniqueid;
char *inboxid;
/* legacy upgrade support */
char *legacy_specialuse;
/* replication support */
ptrarray_t name_history;
};

#define MBENTRY_INITIALIZER { NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, \
NULL, NULL, PTRARRAY_INITIALIZER }
NULL, NULL, NULL, PTRARRAY_INITIALIZER }

typedef struct mboxlist_entry mbentry_t;

Expand Down

0 comments on commit a02794d

Please sign in to comment.