[Dovecot] Loadable module
Timo Sirainen
tss at iki.fi
Tue Jul 22 16:11:12 EEST 2003
On Tue, 2003-07-22 at 14:04, Maikel Verheijen wrote:
> When you have time to create the hooks to the various locations within
> dovecot, I am willing to try to make a module to support Maildir
> quota's. Would that be possible with the hooks, and can that be done
> using a plugin as well?
Hmm. You probably want to override mailbox class's (yea, C class :)
expunge, copy and save_*() methods and make them check/update the quota
files.
You can do the above by overriding mail_storage's open_mailbox() method.
Only hook that I'd need to add is the "mail_storage created" where you
can override the open_mailbox().
You probably want to add some own variables to mailbox class (eg.
pointers to original expunge/copy/save* methods). I'm not really sure
how this should be done. A few possibilities:
1) C++ -like class extension. You create:
struct maildir_quota_mailbox {
struct index_mailbox parent; // mbox/maildir uses index_mailbox
// your stuff here
};
And then casting mailbox -> maildir_quota_mailbox.
But this has the problem that you can't create more than one module
which extents a class.
2) A common module_data mapping for all modules. You'd call
struct maildir_quota_data *data = map_lookup(mailbox, "maildir quota");
3) Something more object oriented, piping the requests through possibly
multiple classes:
// more easily described in C++:
mailbox = new acl_mailbox(new quota_mailbox(new maildir_mailbox()));
struct quota_mailbox {
struct mailbox mailbox;
struct mailbox *next_mailbox;
// your own stuff
};
quota_mailbox_init(struct mailbox *next) {
struct quota_mailbox *box = i_new(struct quota_mailbox, 1);
box->next_mailbox = next;
// fill in the functions we want to grab
box->mailbox = quota_mailbox_defaults;
// whatever functions we left NULL, copy them from "next".
mailbox_fill_defaults(&box->mailbox, next);
}
int quota_mailbox_expunge(struct mailbox *box) {
struct quota_mailbox *qbox = (struct quota_mailbox *) mailbox;
if (!qbox->next->expunge(qbox->next))
return FALSE;
return quota_update(qbox);
}
OK. 3) is the best idea :) But it requires a few changes to make it
work.
Actually, I think this is exactly how I want quota and ACLs to be
implemented. No extra interface changes for either one of them.
For quota, you'd want to do something like:
expunge(): nothing special, just update the quota file after expunges
save_next(): Check data istream's size and if it's over quota, fail.
copy(): this is somewhat problematic, if there wasn't the maildir
hardlinks you wouldn't have to touch it at all..
More information about the dovecot
mailing list