My sincere apologies for the subjectless email (my MUA should have caught that!); the above is the corrected subject line.
-'f
On Wed, 2012-01-11 at 10:53 -0800, Geoffrey Broadwell wrote:
I'm working on a Dovecot plugin, but I'm pretty new to Dovecot, so there's a LOT to learn about the code base and it's pretty slow going. I've got a few things coded so far, but I want to make sure I'm headed down the right path and get some advice before I go too much further.
A couple years ago, I wrote some code for our Courier implementation that sent a magic UDP packet to a small server each time a user modified their voicemail IMAP folder. That UDP server would then connect back to Courier via IMAP again and check whether the folder had any unread messages left in it. Finally, it would contact our phone switches to modify the state of the message waiting indicator (MWI) on that user's phone line appropriately.
Fast forward to now, and we want to migrate wholesale to Dovecot 2.x. The servers are all in place, they've been well tested and burned in (with Dovecot 2.0.15 I believe), and the final migration is pretty much waiting on a port to Dovecot of the MWI update functionality.
The good news is that I originally spent some effort to isolate the UDP packet generation and delivery, and I used purely standard portable code as per APUE2, so I think that chunk of code should be reusable with only minor modifications. I'm aware that internally Dovecot has its own memory, buffer, and string management functions, but it doesn't feel like a win to try to convert the existing code. It's small, completely isolated, and well reviewed -- I'd be more afraid of using the new (to me) Dovecot API incorrectly than I am that the existing code has bugs in buffer handling.
By cribbing from other plugins and editing appropriately, I've also created the skeleton for my plugin: Makefile, docs, conf snippet, .spec (I'll be deploying the plugin as an RPM), and so on. I've got the beginnings of the .h and .c written, just enough to init and deinit the plugin by calling mail_storage_hooks_{add,remove}() with some stub hook functions. This all seems good so far; test builds are error-free and seem sane.
So now the hard part is writing the piece that I can't just crib from elsewhere -- making sure that I hook every place in Dovecot that the user's voicemail folder can be changed in a way that would change it between having one or more unread messages, and not having any unread messages at all (or vice-versa, of course). At the same time, I want to minimize the performance impact to Dovecot (and the load on the UDP server) by only hooking the places I need to, filtering out as many false positives as I can without introducing massive complexity, and only pinging the UDP server when it's most likely to notice a change in the state of that user's voicemail server.
It seems to me that I need to at least capture mailbox_allocated from the mail_storage hooks, for a couple reasons:
1. The state of the voicemail folder could be changed because the entire folder is created, destroyed, or renamed. 2. I want to only do further checks when I'm sure I'm looking at the voicemail folder. There's no reason to do work when the user is working with any other folder.
So now the questions:
Does all of the above seem sane so far?
Do I need to hook mail_allocated as well, or will I be able to see any change I need to monitor just from the mailbox?
Finally, I'm lost about what operations on the mailbox and the mails within it I need to check. Can anyone offer some advice (or doc pointers) on this?
Thank you!
-'f