Attached you will find a finished version of the patch. Please consider adding it to Cyrus 2.1.0pre.
Comments and fixes are very welcome. New Debian pre-release packages are available in people.debian.org/~hmh/cyrus2 (use at own risk). Minimal testing of the patch was done, and it worked well. New options for imapd.conf are: notifysieve: "none" notifymail: "none" valid values are: "none" (the default), "daemon" (== notify_unix.o), "zephyr" Zephyr is only available if --with-zephyr was told to configure. "daemon" is always available, and so is "none". file imap/notify_no.c should be removed, as it is no longer used. file imap/notify.c is new. Patch against HEAD branch of cvs of 2001-11-25. You will need to rerun aclocal, autoheader, autoconf to rebuild the GNU autotools set, as acconfig.h and configure.in were changed. The lines in the patch file are a bit skewed, as I have removed other stuff from the diff. A non-braindead patch utility (e.g. GNU's newest one) will handle that just fine, though. Enjoy! :-) PS: Next task is to get cyrus master to take proper care of the stuff it spawns, just like init does... but this one will take a bit more time to get done. -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
--- cyrus21-imapd-2.1.0.0preCVS20011125.orig/acconfig.h +++ cyrus21-imapd-2.1.0.0preCVS20011125/acconfig.h @@ -54,6 +54,9 @@ /* do we have kerberos? */ #undef HAVE_KRB +/* do we have zephyr? */ +#undef HAVE_ZEPHYR + /* do we already have sys_errlist? */ #undef NEED_SYS_ERRLIST --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/configure.in +++ cyrus21-imapd-2.1.0.0preCVS20011125/configure.in @@ -563,7 +565,7 @@ dnl dnl Test for Zephyr dnl -AC_ARG_WITH(zephyr,[ --with-zephyr=PATH use Zephyr from PATH], +AC_ARG_WITH(zephyr,[ --with-zephyr[=PATH] enable Zephyr notification (installed +on PATH)], with_zephyr="${withval}") if test -z "$with_zephyr"; then if test -f /usr/local/lib/libzephyr.a; then @@ -587,22 +589,12 @@ esac AC_SUBST(ZEPHYR_LIBS) AC_SUBST(ZEPHYR_CPPFLAGS) -AC_ARG_WITH(notify,[ --with-notify=METHOD use mail notification METHOD - METHOD is zephyr, unix or no], - WITH_NOTIFY="${withval}", - if test "$with_zephyr" = "no"; then - WITH_NOTIFY=no - else - WITH_NOTIFY=zephyr - fi) -AC_SUBST(WITH_NOTIFY) -if test "$with_zephyr" = "no"; then - if test "$WITH_NOTIFY" = "zephyr"; then - AC_MSG_ERROR(Unable to find Zephyr libraries) - fi -fi - - +NOTIFY_ZEPHYR="" +if test "x$ZEPHYR_LIBS" != "x" ; then + NOTIFY_ZEPHYR="notify_zephyr.o" + AC_DEFINE(HAVE_ZEPHYR) +fi +AC_SUBST(NOTIFY_ZEPHYR) dnl dnl Select a method for IMAP IDLE --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/Makefile.in +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/Makefile.in @@ -49,7 +49,7 @@ SEEN=seen_db.o # New mail notification mechanism -NOTIFY=notify_@WITH_NOTIFY@.o +NOTIFY=notify.o notify_unix.o @NOTIFY_ZEPHYR@ # IMAP IDLE mechanism IDLE=idle_@WITH_IDLE@.o --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/config.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/config.c @@ -60,6 +60,7 @@ #include "mboxlist.h" #include "util.h" #include "imap_err.h" +#include "notify.h" extern int errno; @@ -79,11 +80,30 @@ const char *config_defpartition; /* /var/spool/imap */ const char *config_newsspool; /* /var/spool/news */ const char *config_servername; /* gethostname() */ +int config_notifysieve; /* 0 (none) */ +int config_notifymail; /* 0 (none) */ int config_hashimapspool; /* f */ static void config_read(const char *alt_config); +int config_notify_server(const char* config_option_name) +{ + if (!config_option_name || + strcasecmp(config_option_name, "none") == 0) { + return NOTIFY_SERVICE_NONE; + } else if (strcasecmp(config_option_name, "daemon") == 0) { + return NOTIFY_SERVICE_UNIX; + } else if (strcasecmp(config_option_name, "zephyr") == 0) { +#ifdef HAVE_ZEPHYR + return NOTIFY_SERVICE_ZEPHYR; +#else + fatal("config_notify_server: Zephyr support not compiled in", +EC_CONFIG); +#endif + } + fatal("config_notify_server: unknown notification service type", EC_CONFIG); +} + int config_init(const char *alt_config, const char *ident) { char buf[100]; --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/imapconf.h +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/imapconf.h @@ -53,6 +53,7 @@ extern int config_getswitch(const char *key, int def); extern const char *config_partitiondir(const char *partition); extern int config_changeident(const char *ident); +extern int config_notify_server(const char* config_option_name); /* sasl configuration */ extern int mysasl_config(void *context, @@ -74,6 +75,9 @@ extern const char *config_servername; extern int config_hashimapspool; + +extern int config_notifysieve; +extern int config_notifymail; void config_scanpartition( void (*proc)() ); --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/lmtpd.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/lmtpd.c @@ -165,7 +165,8 @@ #endif /* per-user/session state */ -static struct protstream *deliver_out, *deliver_in; +static struct protstream *deliver_out = NULL; +static struct protstream *deliver_in = NULL; /* current namespace */ static struct namespace lmtpd_namespace; @@ -265,6 +266,8 @@ } else { sieve_dir = NULL; } + config_notifysieve = config_notify_server( + config_getstring("notifysieve", (char *)0) ); mylmtp.addheaders = xmalloc(80); snprintf(mylmtp.addheaders, 80, "X-Sieve: %s\r\n", SIEVE_VERSION); @@ -273,6 +276,9 @@ setup_sieve(); #endif /* USE_SIEVE */ + config_notifymail = config_notify_server( + config_getstring("notifymail", (char *)0) ); + singleinstance = config_getswitch("singleinstancestore", 1); BB = config_getstring("postuser", BB); @@ -780,7 +786,8 @@ snmp_increment(SIEVE_NOTIFY, 1); - notify("SIEVE", + notify(config_notifysieve, + "SIEVE", nc->priority, sd->username, NULL, @@ -1128,7 +1135,7 @@ if (!r && user) { /* do we want to replace user.XXX with INBOX? */ - notify("MAIL", mailboxname, user, mailboxname, + notify(config_notifymail, "MAIL", mailboxname, user, mailboxname, notifyheader ? notifyheader : ""); } @@ -1304,8 +1311,13 @@ void fatal(const char* s, int code) { - prot_printf(deliver_out,"421 4.3.0 lmtpd: %s\r\n", s); - prot_flush(deliver_out); + if (deliver_out) { + prot_printf(deliver_out,"421 4.3.0 lmtpd: %s\r\n", s); + prot_flush(deliver_out); + } + else { + syslog(LOG_ERR, s); + } exit(code); } --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/lmtpproxyd.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/lmtpproxyd.c @@ -99,7 +99,8 @@ #include "lmtpengine.h" #include "lmtpstats.h" -struct protstream *deliver_out, *deliver_in; +struct protstream *deliver_out = NULL; +struct protstream *deliver_in = NULL; extern int optind; extern char *optarg; @@ -269,6 +270,9 @@ #ifdef USE_SIEVE sieve_dir = config_getstring("sievedir", "/usr/sieve"); + config_notifysieve = config_notify_server( + config_getstring("notifysieve", (char *)0) ); + mylmtp.addheaders = xmalloc(80); snprintf(mylmtp.addheaders, 80, "X-Sieve: %s\r\n", SIEVE_VERSION); @@ -759,7 +763,8 @@ snmp_increment(SIEVE_NOTIFY, 1); - notify("SIEVE", + notify(config_notifysieve, + "SIEVE", nc->priority, sd->username, NULL, @@ -1409,8 +1414,13 @@ void fatal(const char* s, int code) { - prot_printf(deliver_out,"421 4.3.0 deliver: %s\r\n", s); - prot_flush(deliver_out); + if (deliver_out) { + prot_printf(deliver_out,"421 4.3.0 deliver: %s\r\n", s); + prot_flush(deliver_out); + } + else { + syslog(LOG_ERR, s); + } exit(code); } --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/notify.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/notify.c @@ -0,0 +1,74 @@ +/* notify.c -- Switch to call proper notify_* module + $Id: notify.c,v 1.1 2001/12/01 00:57:39 hmh Exp $ + + * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * [EMAIL PROTECTED] + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "config.h" +#include "notify.h" +#include <syslog.h> + +const char *notify_method_desc = "runtime configurable"; + +void notify(const int service_id, + const char *class, + const char *instance, + const char *user, + const char *mailbox, + const char *message) +{ + switch (service_id) { + case NOTIFY_SERVICE_NONE: + break; + case NOTIFY_SERVICE_UNIX: + notify_unix(class, instance, user, mailbox, message); + break; + case NOTIFY_SERVICE_ZEPHYR: +#ifdef HAVE_ZEPHYR + notify_zephyr(class, instance, user, mailbox, message); +#else + syslog(LOG_ERR, "INTERNAL ERROR: Zephyr notification +requested, but not compiled in; skipping..."); +#endif + break; + default: + syslog(LOG_ERR, "INTERNAL ERROR: illegal notify service id %x +requested, skipping...", service_id); + break; + } +} --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/notify.h +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/notify.h @@ -1,4 +1,4 @@ -/* notify.h -- abstract interface for notifications +/* notify.h -- interface for notification switch and modules $Id: notify.h,v 1.3 2001/10/02 21:08:11 ken3 Exp $ * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved. * @@ -43,9 +43,15 @@ #ifndef NOTIFY_H #define NOTIFY_H +/* Notify services IDs */ +#define NOTIFY_SERVICE_NONE 0 +#define NOTIFY_SERVICE_UNIX 1 +#define NOTIFY_SERVICE_ZEPHYR 2 + extern const char *notify_method_desc; -void notify(const char *class, +void notify(const int service_id, + const char *class, const char *instance, const char *user, const char *mailbox, --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/notify_unix.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/notify_unix.c @@ -17,11 +17,9 @@ #include "retry.h" #include "notify.h" -const char *notify_method_desc = "unix"; - #define FNAME_NOTIFY_SOCK "/socket/notify" -void notify(const char *class, +void notify_unix(const char *class, const char *instance, const char *user, const char *mailbox, --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/imap/notify_zephyr.c +++ cyrus21-imapd-2.1.0.0preCVS20011125/imap/notify_zephyr.c @@ -67,8 +67,6 @@ #include "notify.h" -const char *notify_method_desc = "zephyr"; - extern int errno; /* This code is mostly stolen from zpopnotify, from the Zephyr dist. */ @@ -78,7 +76,7 @@ return 1; } -void notify(const char *class, +void notify_zephyr(const char *class, const char *instance, const char *user, const char *mailbox, --- cyrus21-imapd-2.1.0.0preCVS20011125.orig/man/imapd.conf.5 +++ cyrus21-imapd-2.1.0.0preCVS20011125/man/imapd.conf.5 @@ -106,6 +106,14 @@ .IP "\fBquotawarn:\fR 90" 5 The percent of quota utilization over which the server generates warnings. +.IP "\fBnotifymail:\fR none" 5 +How we want to notify that new email arrived. Possible values are +"none" for no notification, "daemon" for notification sent to a unix daemon +and "zephyr", for notification through Zephyr. +.IP "\fBnotifysieve:\fR none" 5 +How we want to notify when such is requested by a seive script. Possible values +are "none" for no notification, "daemon" for notification sent to a unix daemon +and "zephyr", for notification through Zephyr. .IP "\fBtimeout:\fR 30" 5 The length of the IMAP server's inactivity autologout timer, in minutes. The minimum value is 30, the default.