From d4ef9ede288d8d297fd465f91a6ba8c053213e4b Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Mar 25 2008 10:20:30 +0000 Subject: - update to latest upstream - (temporarily) dropped the rmquota+deletemailbox patch (doesn't apply) --- diff --git a/cyrus-imapd-2.3.11-autocreate-0.10-0.diff b/cyrus-imapd-2.3.11-autocreate-0.10-0.diff new file mode 100644 index 0000000..b68d68a --- /dev/null +++ b/cyrus-imapd-2.3.11-autocreate-0.10-0.diff @@ -0,0 +1,2386 @@ +diff -Naur cyrus-imapd-2.3.11/README.autocreate cyrus-imapd-2.3.11-autocreate.uncompiled/README.autocreate +--- cyrus-imapd-2.3.11/README.autocreate 1970-01-01 02:00:00.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/README.autocreate 2007-12-12 13:29:49.000000000 +0200 +@@ -0,0 +1,211 @@ ++Cyrus IMAP autocreate Inbox patch ++---------------------------------- ++ ++NOTE : This patch has been created at the University of Athens. For more info, as well ++as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr/ ++ ++The design of Cyrus IMAP server does not predict the automatic creation of users' ++INBOX folders. The creation of a user's INBOX is considered to be an external task, ++that has to be completed as part of the user email account creation procedure. ++Hence, to create a new email account the site administrator has to: ++ ++ a) Include the new account in the user database for the authentication procedure ++ (e.g. sasldb, shadow, mysql, ldap). ++ b) Create the corresponding INBOX folder. ++ ++Alternatively, the user, if succesfully authenticated, may create his own INBOX folder, ++as long as the configuration of the site allows it (see "autocreatequota" in imapd.conf). ++Unlike what not careful readers may think, enabling the "autocreatequota" option, doesn't ++lead to the automatic INBOX folder creation by Cyrus IMAP server. ++In fact, "autocreate" means that the IMAP clients are allowed to automatically create ++the user INBOX. ++ ++This patch adds the functionality of automatic creation of the users' INBOX folders into ++the Cyrus IMAP server. It is implemented as two features, namely the "create on login" ++and "create on post". ++ ++ ++ ++Create on login ++=============== ++This feauture provides automatic creation of a user's INBOX folder when all of the ++following requirements are met: ++ ++i) The user has succesfully passed the authentication procedure. ++ ++ii) The user's authorisation ID (typically the same as the user's ++authentication ID) doesn't belong to the imap_admins or admins ++accounts (see imapd.conf). ++ ++iii) The "autocreatequota" option in the imap configuration file ++has been set to a non zero value. ++ ++iv) The corresponding to the user's authorisation ID INBOX folder ++does not exist. ++ ++The user's first login is the most typical case when all four requirements are met. ++Note that if the authenticated ID is allowed to proxy to another account for which ++all of the above requirements are met, the corresponding INBOX folder for that account ++will be created. ++ ++ ++ ++Create on post ++============== ++This feauture provides automatic creation of a user's INBOX folder when all of the ++following requirements are met. ++ ++i) An email message addressed to the user has been received. ++ ++ii) The recipient is not any of the imap_admins or admins accounts. ++Note that passing emails to admins or imap_admins accounts from ++the MTA to LMTP should be avoided in any case. ++ ++iii) The recipient's INBOX does not exist. ++ ++iv) The "autocreatequota" option in the imap configuration file ++has been set to a non zero value. ++ ++v) The "createonpost" option in the imap configuration file ++has been switched on. ++ ++ ++Besides the automatic creation of INBOX folder, additional functionalities are ++provided: ++ ++ (A) Automatic creation of INBOX subfolders controlled by "autocreateinboxfolders" ++configuration option. eg ++ ++autocreateinboxfolders: sent|drafts|spam|templates ++ ++ (B) Automatic subscription of INBOX subfolders controlled by "autosubscribeinboxfolders" ++configuration option. eg ++ ++autosubscribeinboxfolders: sent|spam ++ ++Obviously, only subscription to subfolders included in the "autocreateinboxfolder" ++list is meaningful. ++ ++ (C) Automatic subscription to shared folders (bulletin boards). The user gets ++automatically subscribed to the shared folders declared in the "autosubscribesharedfolders" ++configuration option in imapd.conf. ++eg autosubscribesharedfolders: public_folder | public_folder.subfolder ++ ++In order the above action to succeed, the shared folder has to pre-exist the INBOX creation ++and the user must have the appropriate permissions in order to be able to subscribe to the ++shared folder. ++ ++* A new config option has been added. 'autosubscribe_all_sharedfolders' is a yes/no ++option. When set to yes, the user is automatically subscribed to all shared folders one ++has permission to subscribe to. Please, note that when this option is set to yes, then ++'autosubscribesharedfolders' option is overriden. ++ ++ (D) Automatic creation of a predefined default sieve script. ++ ++This is very useful when a default sieve script is used for every user. Usually, a ++default anti-spam script may me be written in a file and copied to each user ++sieve scripts upon the INBOX creation. The imapd.conf options that have been added ++are 'autocreate_sieve_script', 'autocreate_sieve_compiledscript' and ++'generate_compiled_sieve_script'. ++ ++autocreate_sieve_script configuration option refers to the full path of the file ++that contains the sieve script. The default value is null and if no file is defined, ++then no default script is created upon INBOX creation. (The feature is disabled) ++eg autocreate_sieve_script: /etc/default_sieve_script ++ ++autocreate_sieve_compiledscript configuration option refers to the full path of the ++file that contains the bytecode compiled sieve script. If this filename is defined ++in imapd.conf and the file exists, then it is automatically copied in the user's sieve ++directory. If it is not defined, then a bytecode sieve script gets on the fly compiled ++by the daemon. ++eg autocreate_sieve_compiledscript: /etc/default_sieve_script.bc ++ ++generate_compiled_sieve_script is a boolean option that triggers the compilation of the ++source sieve script to bytecode sieve script. The file that the bytecode script will ++be saved is pointed by autocreate_sieve_compiledscript. ++ ++Ways of compiling a sieve script : ++1. Compile a sieve script using the standard sievec utility, distributed by CMU ++2. Compile a sieve script using the compile_sieve utility, released by UoA. This ++ tool is almost identical to the sievec utility, with the difference that it ++ reads the input and output file from autocreate_sieve_script and ++ autocreate_sieve_compiledscript options in imapd.conf ++3. Let cyrus create a compiled sieve script using a source script. Cyrus can be ++ instructed to save the compiled script any time a compiled script does not exist. ++ ++NOTES : ++1. In order this functionality to work, the following requirements must have been met: ++ - 'sieveusehomedir' option must be 'no' in the configuration (default). ++ - 'sievedir' option must have a valid value. ++2. Currently, this patch checks the validity of the source script while generating a ++ bytecode compiled script, but not the validity of the bytecode sieve script file. ++ The administrator should make sure that the provided files contain a valid sieve ++ script as well as the compiled script is updated every time the source script changes. ++ ++ ++ (E) The administrator may control for which users and/or groups may the INBOXes ++automatically be created. The autocreate_users option restricts the groups ++for which the patch will create the mailboxes. ++ ++The default value of autocreate_users is anyone. So, if not set at all, the patch will ++work for all users. However, one may set: ++ ++autocreate_users: user1 user2 group:group1 group:group2 ++ ++In that case, the INBOX will be created only for user1, user2 and the users that belong ++to group1 and group2. ++ ++More refined control per service is provided by the options imap_autocreate_users, ++pop3_autocreate_users and lmtp_autocreate_users. These options override the ++autocreate_users option and offer per service control. ++ ++Example: ++One may want to restrict the create on post functionality only for a specific group ++of users. To achieve this, the following lines must be added in the imapd.conf file: ++ ++createonpost: yes ++lmtp_autocreate_users: group:groupname ++ ++ ++ ++Issues to be considered ++======================= ++ ++I) In order to use the create on post feauture one should be absolutely sure that: ++a) The MTA checks the validity of the email recipient before sending the email to ++LMTP. This is an RFC821 requirement. This usually expands to "the mta should be ++able to use the account database as user mailbox database". ++b) Only authorised accounts/services can talk to LMTP. ++ ++II) Especially in the case of imap logins, the current patch implementation checks ++for the INBOX folder existence upon login, causing an extra mailbox lookup in most ++of the cases. ++A better approach would be to chase the "IMAP_MAILBOX_NONEXISTENT" error code and ++check if the error is associated with an INBOX folder. However, this would mess up ++Cyrus code. The way it was implemented may not have been the most performance ++optimised, but it produces a much cleaner and simple patch. ++ ++ ++ ++Virtual Domains Support ++======================= ++ ++Virtual domains are supported by all versions of the patch for cyrus-imapd-2.2.1-BETA and ++later. However, it is not possible to declare different INBOX subfolders to be created or ++shared folders to be subscribed to for every domain. ++ ++ ++ ++Things to be done ++================= ++ ++1. Support MUPDATE ++ ++It is within the developers' intentions to support the mupdate protocol, but serious ++design issues on future cyrus releases have to resolved first. ++ ++2. Select different attributes (quota, partition, sieve filter, etc) depending on the group ++a user belongs to. ++ ++For more information and updates please visit http://email.uoa.gr/projects/cyrus/autocreate ++ +diff -Naur cyrus-imapd-2.3.11/imap/Makefile.in cyrus-imapd-2.3.11-autocreate.uncompiled/imap/Makefile.in +--- cyrus-imapd-2.3.11/imap/Makefile.in 2007-10-18 21:48:02.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/Makefile.in 2007-12-12 13:29:49.000000000 +0200 +@@ -101,7 +101,7 @@ + convert_code.o duplicate.o saslclient.o saslserver.o signals.o \ + annotate.o search_engines.o squat.o squat_internal.o mbdump.o \ + imapparse.o telemetry.o user.o notify.o protocol.o idle.o quota_db.o \ +- sync_log.o $(SEEN) mboxkey.o backend.o tls.o message_guid.o ++ sync_log.o autosieve.o $(SEEN) mboxkey.o backend.o tls.o message_guid.o + + IMAPDOBJS=pushstats.o imapd.o proxy.o imap_proxy.o index.o version.o + +@@ -117,7 +117,7 @@ + fud smmapd reconstruct quota mbpath ipurge cyr_dbtool cyr_synclog \ + cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \ + ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \ +- unexpunge @IMAP_PROGS@ ++ unexpunge compile_sieve @IMAP_PROGS@ + + BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \ + lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \ +@@ -182,9 +182,9 @@ + mupdate_err.h: mupdate_err.c + + ### Services +-idled: idled.o mutex_fake.o libimap.a $(DEPLIBS) ++idled: idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o idled \ +- idled.o mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) ++ idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + + lmtpd: lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o \ + libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) +@@ -198,158 +198,162 @@ + $(SERVICE) lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) \ + mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + +-imapd: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) ++imapd: $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o imapd \ + $(SERVICE) $(IMAPDOBJS) mutex_fake.o \ +- libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + +-imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) ++imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \ + $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + +-imapd.quant: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) ++imapd.quant: $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(QUANTIFY) $(QUANTOPT) $(CC) $(LDFLAGS) -o imapd.quant \ + $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + + mupdate: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o tls.o \ +- libimap.a $(DEPLIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o mupdate \ + $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \ + mutex_pthread.o tls.o libimap.a \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread + + mupdate.pure: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o \ +- libimap.a $(DEPLIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o mupdate.pure \ + $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \ +- mutex_pthread.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread ++ mutex_pthread.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread + + pop3d: pop3d.o proxy.o backend.o tls.o mutex_fake.o libimap.a \ +- $(DEPLIBS) $(SERVICE) ++ $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o pop3d pop3d.o proxy.o backend.o tls.o $(SERVICE) \ +- mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + + nntpd: nntpd.o proxy.o backend.o index.o smtpclient.o spool.o tls.o \ +- mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE) ++ mutex_fake.o nntp_err.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o nntpd nntpd.o proxy.o backend.o index.o spool.o \ + smtpclient.o tls.o $(SERVICE) mutex_fake.o nntp_err.o \ +- libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + +-fud: fud.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) ++fud: fud.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o fud $(SERVICE) fud.o mutex_fake.o libimap.a \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + +-smmapd: smmapd.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) ++smmapd: smmapd.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o smmapd $(SERVICE) smmapd.o mutex_fake.o libimap.a \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + + sync_server: sync_server.o sync_support.o sync_commit.o \ +- imapparse.o tls.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) ++ imapparse.o tls.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) + $(CC) $(LDFLAGS) -o \ + sync_server sync_server.o sync_support.o sync_commit.o \ + imapparse.o tls.o $(SERVICE) libimap.a mutex_fake.o \ +- $(DEPLIBS) $(LIBS) $(LIB_WRAP) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) + + ### Command Line Utilities +-arbitron: arbitron.o $(CLIOBJS) libimap.a $(DEPLIBS) ++arbitron: arbitron.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o arbitron arbitron.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-cyr_dbtool: cyr_dbtool.o mutex_fake.o libimap.a $(DEPLIBS) ++cyr_dbtool: cyr_dbtool.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o cyr_dbtool cyr_dbtool.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-cyr_synclog: cyr_synclog.o mutex_fake.o libimap.a $(DEPLIBS) ++cyr_synclog: cyr_synclog.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o cyr_synclog cyr_synclog.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(DEPLIBS) ++cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o cvt_cyrusdb cvt_cyrusdb.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(DEPLIBS) ++chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o chk_cyrus chk_cyrus.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-deliver: deliver.o $(LMTPOBJS) proxy.o mutex_fake.o libimap.a $(DEPLIBS) ++deliver: deliver.o $(LMTPOBJS) proxy.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o deliver deliver.o $(LMTPOBJS) proxy.o \ +- mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) ++ mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) ++ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- $@ ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ $@ ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(DEPLIBS) ++ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o $@ ctl_mboxlist.o mupdate-client.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) ++ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(DEPLIBS) ++cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o $@ cyr_expire.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) ++fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- $@ fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ $@ fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(DEPLIBS) ++squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o squatter squatter.o index.o squat_build.o \ +- $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-mbpath: mbpath.o $(CLIOBJS) libimap.a $(DEPLIBS) ++mbpath: mbpath.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o mbpath mbpath.o $(CLIOBJS) libimap.a \ +- $(DEPLIBS) $(LIBS) ++ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-ipurge: ipurge.o $(CLIOBJS) libimap.a $(DEPLIBS) ++ipurge: ipurge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o ipurge ipurge.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(DEPLIBS) ++cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o cyrdump cyrdump.o index.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) ++mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- mbexamine mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ mbexamine mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) ++reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- reconstruct reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ reconstruct reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-quota: quota.o $(CLIOBJS) libimap.a $(DEPLIBS) ++quota: quota.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o quota quota.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) ++tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ +- $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) ++ $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-unexpunge: unexpunge.o $(CLIOBJS) libimap.a $(DEPLIBS) ++unexpunge: unexpunge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o $@ unexpunge.o $(CLIOBJS) \ +- libimap.a $(DEPLIBS) $(LIBS) ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-make_md5: make_md5.o libimap.a mutex_fake.o $(DEPLIBS) +- $(CC) $(LDFLAGS) -o make_md5 make_md5.o libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) ++make_md5: make_md5.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) ++ $(CC) $(LDFLAGS) -o make_md5 make_md5.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + +-make_sha1: make_sha1.o libimap.a mutex_fake.o $(DEPLIBS) +- $(CC) $(LDFLAGS) -o make_sha1 make_sha1.o libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) ++make_sha1: make_sha1.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) ++ $(CC) $(LDFLAGS) -o make_sha1 make_sha1.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + + sync_client: sync_client.o sync_support.o \ +- backend.o tls.o imapparse.o libimap.a mutex_fake.o $(DEPLIBS) ++ backend.o tls.o imapparse.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ + sync_client sync_client.o sync_support.o \ +- backend.o tls.o imapparse.o libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) ++ backend.o tls.o imapparse.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + + sync_reset: sync_reset.o sync_support.o sync_commit.o \ +- libimap.a mutex_fake.o $(DEPLIBS) ++ libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) + $(CC) $(LDFLAGS) -o \ + sync_reset sync_reset.o sync_support.o sync_commit.o \ +- libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) ++ libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) ++ ++compile_sieve: compile_sieve.o libimap.a $(DEPLIBS) $(SIEVE_LIBS) ++ $(CC) $(LDFLAGS) -o compile_sieve compile_sieve.o $(CLIOBJS) \ ++ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) + + ### Other Misc Targets + +diff -Naur cyrus-imapd-2.3.11/imap/autosieve.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/autosieve.c +--- cyrus-imapd-2.3.11/imap/autosieve.c 1970-01-01 02:00:00.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/autosieve.c 2007-12-12 13:29:49.000000000 +0200 +@@ -0,0 +1,590 @@ ++#include ++#include ++#include ++ ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "global.h" ++#include "util.h" ++#include "xmalloc.h" ++#include "xstrlcpy.h" ++#include "xstrlcat.h" ++#include "mailbox.h" ++#include "imap_err.h" ++#include "sieve_interface.h" ++#include "script.h" ++ ++#define TIMSIEVE_FAIL -1 ++#define TIMSIEVE_OK 0 ++#define MAX_FILENAME 1024 ++ ++static int get_script_name(char *sievename, size_t buflen, const char *filename); ++static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir); ++int autoadd_sieve(char *userid, const char *source_script); ++ ++//static void fatal(const char *s, int code); ++static void foo(void); ++static int sieve_notify(void *ac __attribute__((unused)), ++ void *interp_context __attribute__((unused)), ++ void *script_context __attribute__((unused)), ++ void *message_context __attribute__((unused)), ++ const char **errmsg __attribute__((unused))); ++static int mysieve_error(int lineno, const char *msg, ++ void *i __attribute__((unused)), void *s); ++static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret); ++ ++ ++sieve_vacation_t vacation2 = { ++ 0, /* min response */ ++ 0, /* max response */ ++ (sieve_callback *) &foo, /* autorespond() */ ++ (sieve_callback *) &foo /* send_response() */ ++}; ++ ++ ++/* ++ * Find the name of the sieve script ++ * given the source script and compiled script names ++ */ ++static int get_script_name(char *sievename, size_t buflen, const char *filename) ++{ ++ char *p; ++ int r; ++ ++ p = strrchr(filename, '/'); ++ if (p == NULL) ++ p = (char *) filename; ++ else ++ p++; ++ ++ r = strlcpy(sievename, p, buflen) - buflen; ++ return (r >= 0 || r == -buflen ? 1 : 0); ++} ++ ++ ++/* ++ * Find the directory where the sieve scripts of the user ++ * reside ++ */ ++static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir) ++{ ++ char *user = NULL, *domain = NULL; ++ ++ /* Setup the user and the domain */ ++ if(config_virtdomains && (domain = strchr(userid, '@'))) { ++ user = (char *) xmalloc((domain - userid +1) * sizeof(char)); ++ strlcpy(user, userid, domain - userid + 1); ++ domain++; ++ } else ++ user = userid; ++ ++ /* Find the dir path where the sieve scripts of the user will reside */ ++ if (config_virtdomains && domain) { ++ if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/", ++ sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain, config_fulldirhash), domain, dir_hash_c(user,config_fulldirhash), user) >= buflen) { ++ free(user); ++ return 1; ++ } ++ } else { ++ if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/", ++ sieve_dir, dir_hash_c(user,config_fulldirhash), user) >= buflen) ++ return 1; ++ } ++ ++ /* Free the xmalloced user memory, reserved above */ ++ if(user != userid) ++ free(user); ++ ++ return 0; ++} ++ ++int autoadd_sieve(char *userid, const char *source_script) ++{ ++ sieve_script_t *s = NULL; ++ bytecode_info_t *bc = NULL; ++ char *err = NULL; ++ FILE *in_stream, *out_fp; ++ int out_fd, in_fd, r, k; ++ int do_compile = 0; ++ const char *sieve_dir = NULL; ++ const char *compiled_source_script = NULL; ++ char sievename[MAX_FILENAME]; ++ char sieve_script_name[MAX_FILENAME]; ++ char sieve_script_dir[MAX_FILENAME]; ++ char sieve_bcscript_name[MAX_FILENAME]; ++ char sieve_default[MAX_FILENAME]; ++ char sieve_tmpname[MAX_FILENAME]; ++ char sieve_bctmpname[MAX_FILENAME]; ++ char sieve_bclink_name[MAX_FILENAME]; ++ char buf[4096]; ++ mode_t oldmask; ++ struct stat statbuf; ++ ++ /* We don't support using the homedirectory, like timsieved */ ++ if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) { ++ syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf"); ++ return 1; ++ } ++ ++ /* Check if sievedir is defined in imapd.conf */ ++ if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) { ++ syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf"); ++ return 1; ++ } ++ ++ /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */ ++ if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) { ++ syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it"); ++ do_compile = 1; ++ } ++ ++ if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory"); ++ return 1; ++ } ++ ++ if (get_script_name(sievename, sizeof(sievename), source_script)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script); ++ return 1; ++ } ++ ++ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); ++ return 1; ++ } ++ ++ /* Check if a default sieve filter alrady exists */ ++ if(!stat(sieve_default,&statbuf)) { ++ syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists"); ++ fclose(in_stream); ++ return 1; ++ } ++ ++ /* Open the source script. if there is a problem with that exit */ ++ in_stream = fopen(source_script, "r"); ++ if(!in_stream) { ++ syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script); ++ return 1; ++ } ++ ++ ++ /* ++ * At this point we start the modifications of the filesystem ++ */ ++ ++ /* Create the directory where the sieve scripts will reside */ ++ r = cyrus_mkdir(sieve_script_dir, 0755); ++ if(r == -1) { ++ /* If this fails we just leave */ ++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name); ++ return 1; ++ } ++ ++ /* ++ * We open the file that will be used as the bc file. If this file exists, overwrite it ++ * since something bad has happened. We open the file here so that this error checking is ++ * done before we try to open the rest of the files to start copying etc. ++ */ ++ out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); ++ if(out_fd < 0) { ++ if(errno == EEXIST) { ++ syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname); ++ } else if (errno == EACCES) { ++ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname); ++ fclose(in_stream); ++ return 1; ++ } else { ++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname); ++ fclose(in_stream); ++ return 1; ++ } ++ } ++ ++ if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) { ++ while((r = read(in_fd, buf, sizeof(buf))) > 0) { ++ if((k=write(out_fd, buf,r)) < 0) { ++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno); ++ close(out_fd); ++ close(in_fd); ++ fclose(in_stream); ++ unlink(sieve_bctmpname); ++ return 1; ++ } ++ } ++ ++ if(r == 0) { /* EOF */ ++ close(out_fd); ++ close(in_fd); ++ } else if (r < 0) { ++ syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it", ++ compiled_source_script); ++ close(in_fd); ++ do_compile = 1; ++ if(lseek(out_fd, 0, SEEK_SET)) { ++ syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting"); ++ return 1; ++ } ++ } ++ close(in_fd); ++ } else { ++ if(compiled_source_script) ++ syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script); ++ do_compile = 1; ++ } ++ ++ ++ /* Because we failed to open a precompiled bc sieve script, we compile one */ ++ if(do_compile) { ++ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) { ++ if(err && *err) { ++ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err); ++ free(err); ++ } else ++ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script"); ++ ++ unlink(sieve_bctmpname); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ ++ /* generate the bytecode */ ++ if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) { ++ syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script"); ++ /* removing the copied script and cleaning up memory */ ++ unlink(sieve_bctmpname); ++ sieve_script_free(&s); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ ++ if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) { ++ syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script"); ++ /* removing the copied script and cleaning up memory */ ++ unlink(sieve_bctmpname); ++ sieve_free_bytecode(&bc); ++ sieve_script_free(&s); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ ++ /* clean up the memory */ ++ sieve_free_bytecode(&bc); ++ sieve_script_free(&s); ++ } ++ ++ close(out_fd); ++ rewind(in_stream); ++ ++ /* Copy the initial script */ ++ oldmask = umask(077); ++ if((out_fp = fopen(sieve_tmpname, "w")) == NULL) { ++ syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname); ++ unlink(sieve_bctmpname); ++ umask(oldmask); ++ fclose(in_stream); ++ return 1; ++ } ++ umask(oldmask); ++ ++ while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) { ++ if( fwrite(buf,sizeof(char), r, out_fp) != r) { ++ syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname); ++ fclose(out_fp); ++ unlink(sieve_tmpname); ++ unlink(sieve_bctmpname); ++ fclose(in_stream); ++ return 1; ++ } ++ } ++ ++ if(feof(in_stream)) { ++ fclose(out_fp); ++ } else { /* ferror */ ++ fclose(out_fp); ++ unlink(sieve_tmpname); ++ unlink(sieve_bctmpname); ++ fclose(in_stream); ++ return 1; ++ } ++ ++ /* Renaming the necessary stuff */ ++ if(rename(sieve_tmpname, sieve_script_name)) { ++ unlink(sieve_tmpname); ++ unlink(sieve_bctmpname); ++ return 1; ++ } ++ ++ if(rename(sieve_bctmpname, sieve_bcscript_name)) { ++ unlink(sieve_bctmpname); ++ unlink(sieve_bcscript_name); ++ return 1; ++ } ++ ++ /* end now with the symlink */ ++ if(symlink(sieve_bclink_name, sieve_default)) { ++ if(errno != EEXIST) { ++ syslog(LOG_WARNING, "autocreate_sieve: problem making the default link."); ++ /* Lets delete the files */ ++ unlink(sieve_script_name); ++ unlink(sieve_bcscript_name); ++ } ++ } ++ ++ /* ++ * If everything has succeeded AND we have compiled the script AND we have requested ++ * to generate the global script so that it is not compiled each time then we create it. ++ */ ++ if(do_compile && ++ config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) { ++ ++ if(!compiled_source_script) { ++ syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf"); ++ return 0; ++ } ++ ++ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname)) ++ return 0; ++ ++ /* ++ * Copy everything from the newly created bc sieve sieve script. ++ */ ++ if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) { ++ return 0; ++ } ++ ++ if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { ++ if(errno == EEXIST) { ++ /* Someone is already doing this so just bail out. */ ++ syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname); ++ close(in_fd); ++ return 0; ++ } else if (errno == EACCES) { ++ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname); ++ close(in_fd); ++ return 0; ++ } else { ++ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname); ++ close(in_fd); ++ return 0; ++ } ++ } ++ ++ while((r = read(in_fd, buf, sizeof(buf))) > 0) { ++ if((k = write(out_fd,buf,r)) < 0) { ++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno); ++ close(out_fd); ++ close(in_fd); ++ unlink(sieve_tmpname); ++ return 0; ++ } ++ } ++ ++ if(r == 0 ) { /*EOF */ ++ close(out_fd); ++ close(in_fd); ++ } else if (r < 0) { ++ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno); ++ close(out_fd); ++ close(in_fd); ++ unlink(sieve_tmpname); ++ return 0; ++ } ++ ++ /* Rename the temporary created sieve script to its final name. */ ++ if(rename(sieve_tmpname, compiled_source_script)) { ++ if(errno != EEXIST) { ++ unlink(sieve_tmpname); ++ unlink(compiled_source_script); ++ } ++ return 0; ++ } ++ ++ syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script); ++ } ++ ++ return 0; ++} ++ ++/*static void fatal(const char *s, int code) ++{ ++ printf("Fatal error: %s (%d)\r\n", s, code); ++ exit(1); ++}*/ ++ ++/* to make larry's stupid functions happy :) */ ++static void foo(void) ++{ ++ fatal("stub function called", 0); ++} ++ ++static int sieve_notify(void *ac __attribute__((unused)), ++ void *interp_context __attribute__((unused)), ++ void *script_context __attribute__((unused)), ++ void *message_context __attribute__((unused)), ++ const char **errmsg __attribute__((unused))) ++{ ++ fatal("stub function called", 0); ++ return SIEVE_FAIL; ++} ++ ++static int mysieve_error(int lineno, const char *msg, ++ void *i __attribute__((unused)), void *s) ++{ ++ char buf[1024]; ++ char **errstr = (char **) s; ++ ++ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg); ++ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30); ++ syslog(LOG_DEBUG, "%s", buf); ++ strcat(*errstr, buf); ++ ++ return SIEVE_OK; ++} ++ ++/* end the boilerplate */ ++ ++/* returns TRUE or FALSE */ ++int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret) ++{ ++ sieve_interp_t *i; ++ sieve_script_t *s; ++ int res; ++ ++ res = sieve_interp_alloc(&i, NULL); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_redirect(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_discard(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_reject(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_fileinto(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_keep(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_imapflags(i, NULL); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_size(i, (sieve_get_size *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_header(i, (sieve_get_header *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_vacation(i, &vacation2); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_notify(i, &sieve_notify); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_parse_error(i, &mysieve_error); ++ if (res != SIEVE_OK) { ++ syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ rewind(stream); ++ ++ *errstr = (char *) xmalloc(20 * sizeof(char)); ++ strcpy(*errstr, "script errors:\r\n"); ++ ++ res = sieve_script_parse(i, stream, errstr, &s); ++ ++ if (res == SIEVE_OK) { ++ if(ret) { ++ *ret = s; ++ } else { ++ sieve_script_free(&s); ++ } ++ free(*errstr); ++ *errstr = NULL; ++ } ++ ++ /* free interpreter */ ++ sieve_interp_free(&i); ++ ++ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL; ++} ++ ++/* ++ * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of ++ * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present ++ */ ++ +diff -Naur cyrus-imapd-2.3.11/imap/compile_sieve.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/compile_sieve.c +--- cyrus-imapd-2.3.11/imap/compile_sieve.c 1970-01-01 02:00:00.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/compile_sieve.c 2007-12-12 13:29:49.000000000 +0200 +@@ -0,0 +1,365 @@ ++/* This tool compiles the sieve script from a command ++line so that it can be used wby the autoadd patch */ ++#include ++#include ++ ++#include ++#include ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "global.h" ++ ++#include "util.h" ++#include "xmalloc.h" ++#include "xstrlcpy.h" ++#include "xstrlcat.h" ++#include "mailbox.h" ++#include "imap_err.h" ++#include "sieve_interface.h" ++#include "script.h" ++ ++#include ++ ++#define TIMSIEVE_FAIL -1 ++#define TIMSIEVE_OK 0 ++#define MAX_FILENAME_SIZE 100 ++ ++/* Needed by libconfig */ ++const int config_need_data = 0; ++ ++static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret); ++ ++/*static void fatal(const char *s, int code) ++{ ++ printf("Fatal error: %s (%d)\r\n", s, code); ++ ++ exit(1); ++}*/ ++ ++void usage(void) ++{ ++ fprintf(stderr, ++ "Usage:\n\tcompile_sieve [-C ] [-i -o ]\n"); ++ exit(-1); ++} ++ ++ ++int main (int argc, char **argv) ++{ ++ ++ sieve_script_t *s = NULL; ++ bytecode_info_t *bc = NULL; ++ char *err = NULL; ++ FILE *in_stream; ++ int out_fd, opt; ++ char *source_script = NULL; ++ char *compiled_source_script = NULL; ++ char *alt_config = NULL; ++ extern char *optarg; ++ char sieve_tmpname[MAX_MAILBOX_NAME+1]; ++ ++ if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE); ++ ++ while((opt = getopt(argc, argv, "C:i:o:")) != EOF) { ++ switch (opt) { ++ case 'C': /* alt config file */ ++ alt_config = optarg; ++ break; ++ case 'i': /* input script file */ ++ source_script = optarg; ++ break; ++ case 'o': /* output script file */ ++ compiled_source_script = optarg; ++ break; ++ default: ++ usage(); ++ break; ++ } ++ } ++ ++ if(source_script && !compiled_source_script) { ++ fprintf(stderr, "No output file was defined\n"); ++ usage(); ++ } else if (!source_script && compiled_source_script) { ++ fprintf(stderr, "No input file was defined\n"); ++ usage(); ++ } ++ ++ /* ++ * If no has been defined, then read them from ++ * the configuration file. ++ */ ++ if (!source_script && !compiled_source_script) { ++ cyrus_init(alt_config, "compile_sieve", 0); ++ ++ /* Initially check if we want to have the sieve script created */ ++ if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) { ++ fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n"); ++ return 1; ++ } ++ ++ /* Check if we have an already compiled sieve script*/ ++ if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) { ++ fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n"); ++ return 1; ++ } ++ ++ if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) { ++ /* ++ * At this point the only think that is inconsistent is the directory ++ * that was created. But if the user will have any sieve scripts then ++ * they will eventually go there, so no big deal ++ */ ++ fprintf(stderr, ++ "In imapd.conf the full path of the filenames must be defined\n"); ++ return 1; ++ } ++ } ++ ++ printf("input file : %s, output file : %s\n", source_script, compiled_source_script); ++ ++ ++ if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) { ++ fprintf(stderr, "Filename %s is too big\n", compiled_source_script); ++ return 1; ++ } ++ ++ snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script); ++ ++ in_stream = fopen(source_script,"r"); ++ ++ if(!in_stream) { ++ fprintf(stderr,"Unable to open %s source sieve script\n",source_script); ++ return 1; ++ } ++ ++ /* ++ * We open the file that will be used as the bc file. If this file exists, overwrite it ++ * since something bad has happened. We open the file here so that this error checking is ++ * done before we try to open the rest of the files to start copying etc. ++ */ ++ out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); ++ if(out_fd < 0) { ++ if(errno == EEXIST) { ++ fprintf(stderr, "File %s already exists\n", sieve_tmpname); ++ } else if (errno == EACCES) { ++ fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n", ++ sieve_tmpname); ++ } else { ++ fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n", ++ sieve_tmpname); ++ } ++ ++ fclose(in_stream); ++ return 1; ++ } ++ ++ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) { ++ if(err && *err) { ++ fprintf(stderr, "Error while parsing script %s\n",err); ++ free(err); ++ } ++ else ++ fprintf(stderr,"Error while parsing script\n"); ++ unlink(sieve_tmpname); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ ++ ++ /* generate the bytecode */ ++ if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) { ++ fprintf(stderr,"Error occured while compiling sieve script\n"); ++ /* removing the copied script and cleaning up memory */ ++ unlink(sieve_tmpname); ++ sieve_script_free(&s); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) { ++ fprintf(stderr, "Error occured while emitting sieve script\n"); ++ unlink(sieve_tmpname); ++ sieve_free_bytecode(&bc); ++ sieve_script_free(&s); ++ fclose(in_stream); ++ close(out_fd); ++ return 1; ++ } ++ ++ /* clean up the memory */ ++ sieve_free_bytecode(&bc); ++ sieve_script_free(&s); ++ ++ close(out_fd); ++ ++ if(rename(sieve_tmpname, compiled_source_script)) { ++ if(errno != EEXIST) { ++ unlink(sieve_tmpname); ++ unlink(compiled_source_script); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++ ++/* to make larry's stupid functions happy :) */ ++static void foo(void) ++{ ++ fatal("stub function called", 0); ++} ++ ++extern sieve_vacation_t vacation2;/* = { ++ 0, / min response / ++ 0, / max response / ++ (sieve_callback *) &foo, / autorespond() / ++ (sieve_callback *) &foo / send_response() / ++}; */ ++ ++static int sieve_notify(void *ac __attribute__((unused)), ++ void *interp_context __attribute__((unused)), ++ void *script_context __attribute__((unused)), ++ void *message_context __attribute__((unused)), ++ const char **errmsg __attribute__((unused))) ++{ ++ fatal("stub function called", 0); ++ return SIEVE_FAIL; ++} ++ ++static int mysieve_error(int lineno, const char *msg, ++ void *i __attribute__((unused)), void *s) ++{ ++ char buf[1024]; ++ char **errstr = (char **) s; ++ ++ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg); ++ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30); ++ fprintf(stderr, "%s\n", buf); ++ strcat(*errstr, buf); ++ ++ return SIEVE_OK; ++} ++ ++/* end the boilerplate */ ++ ++/* returns TRUE or FALSE */ ++int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret) ++{ ++ sieve_interp_t *i; ++ sieve_script_t *s; ++ int res; ++ ++ res = sieve_interp_alloc(&i, NULL); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_interp_alloc() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_redirect(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_redirect() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_discard(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_discard() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_reject(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_reject() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_fileinto(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_fileinto() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ res = sieve_register_keep(i, (sieve_callback *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_keep() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_imapflags(i, NULL); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_imapflags() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_size(i, (sieve_get_size *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_size() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_header(i, (sieve_get_header *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_header() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_envelope() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_vacation(i, &vacation2); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_vacation() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_notify(i, &sieve_notify); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_notify() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ res = sieve_register_parse_error(i, &mysieve_error); ++ if (res != SIEVE_OK) { ++ fprintf(stderr, "sieve_register_parse_error() returns %d\n", res); ++ return TIMSIEVE_FAIL; ++ } ++ ++ rewind(stream); ++ ++ *errstr = (char *) xmalloc(20 * sizeof(char)); ++ strcpy(*errstr, "script errors:\r\n"); ++ ++ res = sieve_script_parse(i, stream, errstr, &s); ++ ++ if (res == SIEVE_OK) { ++ if(ret) { ++ *ret = s; ++ } else { ++ sieve_script_free(&s); ++ } ++ free(*errstr); ++ *errstr = NULL; ++ } ++ ++ /* free interpreter */ ++ sieve_interp_free(&i); ++ ++ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL; ++} ++ ++ ++ ++ ++ ++ +diff -Naur cyrus-imapd-2.3.11/imap/imapd.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/imapd.c +--- cyrus-imapd-2.3.11/imap/imapd.c 2007-11-27 17:31:28.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/imapd.c 2007-12-12 13:29:49.000000000 +0200 +@@ -205,6 +205,7 @@ + void motd_file(int fd); + void shut_down(int code); + void fatal(const char *s, int code); ++void autocreate_inbox(void); + + void cmdloop(void); + void cmd_login(char *tag, char *user); +@@ -1907,6 +1908,43 @@ + } + + /* ++ * Autocreate Inbox and subfolders upon login ++ */ ++void autocreate_inbox() ++{ ++ char inboxname[MAX_MAILBOX_NAME+1]; ++ int autocreatequota; ++ int r; ++ ++ /* ++ * Exlude admin's accounts ++ */ ++ if (imapd_userisadmin || imapd_userisproxyadmin) ++ return; ++ ++ /* ++ * Exclude anonymous ++ */ ++ if (!strcmp(imapd_userid, "anonymous")) ++ return; ++ ++ if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { ++ /* This is actyally not required ++ as long as the lenght of userid is ok */ ++ r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace, ++ "INBOX", imapd_userid, inboxname); ++ if (!r) ++ r = mboxlist_lookup(inboxname, NULL, NULL); ++ ++ if (r == IMAP_MAILBOX_NONEXISTENT) { ++ mboxlist_autocreateinbox(&imapd_namespace, imapd_userid, ++ imapd_authstate, inboxname, autocreatequota); ++ } ++ } ++} ++ ++ ++/* + * Perform a LOGIN command + */ + void cmd_login(char *tag, char *user) +@@ -2074,6 +2112,9 @@ + strcspn(imapd_userid, "@") : 0); + + freebuf(&passwdbuf); ++ ++ autocreate_inbox(); ++ + return; + } + +@@ -2232,6 +2273,8 @@ + config_virtdomains ? + strcspn(imapd_userid, "@") : 0); + ++ autocreate_inbox(); ++ + return; + } + +diff -Naur cyrus-imapd-2.3.11/imap/lmtpd.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/lmtpd.c +--- cyrus-imapd-2.3.11/imap/lmtpd.c 2007-10-12 15:54:23.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/lmtpd.c 2007-12-12 13:29:49.000000000 +0200 +@@ -117,6 +117,8 @@ + static FILE *spoolfile(message_data_t *msgdata); + static void removespool(message_data_t *msgdata); + ++static int autocreate_inbox(const char *user, const char *domain); ++ + /* current namespace */ + static struct namespace lmtpd_namespace; + +@@ -956,6 +958,86 @@ + exit(code); + } + ++ ++/* ++ * Autocreate Inbox and subfolders upon login ++ */ ++int autocreate_inbox(const char *user, const char *domain) ++{ ++ struct auth_state *auth_state; ++ char inboxname[MAX_MAILBOX_NAME+1]; ++ char *rcpt_userid = NULL; ++ int autocreatequota; ++ int r = 0; ++ ++ if (user == NULL) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ if (domain != NULL) { ++ int k; ++ ++ rcpt_userid = (char *) xmalloc((strlen(user) + strlen(domain) + 2) * sizeof(char)); ++ k = strlcpy(rcpt_userid, user, strlen(user) + 1); ++ *(rcpt_userid + k) = '@'; ++ strlcpy(rcpt_userid + k + 1, domain, strlen(domain) + 1); ++ } else { ++ rcpt_userid = (char *) user; ++ } ++ ++ ++ /* ++ * Exclude anonymous ++ */ ++ if (!strcmp(rcpt_userid, "anonymous")) { ++ if (rcpt_userid != user) { ++ free(rcpt_userid); ++ } ++ ++ return IMAP_MAILBOX_NONEXISTENT; ++ } ++ ++ /* ++ * Check for autocreatequota and createonpost ++ */ ++ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) || ++ !(config_getswitch(IMAPOPT_CREATEONPOST))) { ++ ++ if (rcpt_userid != user) { ++ free(rcpt_userid); ++ } ++ ++ return IMAP_MAILBOX_NONEXISTENT; ++ } ++ ++ ++ /* ++ * Exclude admin's accounts ++ */ ++ auth_state = auth_newstate(rcpt_userid); ++ ++ if (global_authisa(auth_state, IMAPOPT_ADMINS)) { ++ if (rcpt_userid != user) { ++ free(rcpt_userid); ++ } ++ ++ return IMAP_MAILBOX_NONEXISTENT; ++ } ++ ++ r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace, ++ "INBOX", rcpt_userid, inboxname); ++ ++ if (!r) ++ r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid, ++ auth_state, inboxname, autocreatequota); ++ ++ if (rcpt_userid != user) { ++ free(rcpt_userid); ++ } ++ ++ return r; ++} ++ ++ + static int verify_user(const char *user, const char *domain, char *mailbox, + long quotacheck, struct auth_state *authstate) + { +@@ -999,6 +1081,15 @@ + */ + r = mlookup(namebuf, &server, &acl, NULL); + ++ /* If user mailbox does not exist, then invoke autocreate inbox function */ ++ if (r == IMAP_MAILBOX_NONEXISTENT) { ++ r = autocreate_inbox(user, domain); ++ ++ /* Try to locate the mailbox again */ ++ if (!r) ++ r = mlookup(namebuf, &server, &acl, NULL); ++ } ++ + if (r == IMAP_MAILBOX_NONEXISTENT && !user && + config_getswitch(IMAPOPT_LMTP_FUZZY_MAILBOX_MATCH) && + /* see if we have a mailbox whose name is close */ +@@ -1025,6 +1116,7 @@ + aclcheck, (quotacheck < 0) + || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ? + quotacheck : 0); ++ + } + } + +diff -Naur cyrus-imapd-2.3.11/imap/mboxlist.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/mboxlist.c +--- cyrus-imapd-2.3.11/imap/mboxlist.c 2007-11-27 17:31:29.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/mboxlist.c 2007-12-12 13:29:49.000000000 +0200 +@@ -84,6 +84,12 @@ + #include "quota.h" + #include "sync_log.h" + ++#ifdef USE_SIEVE ++extern int autoadd_sieve(char *userid, ++ const char *source_script); ++#endif ++ ++ + #define DB config_mboxlist_db + #define SUBDB config_subscription_db + +@@ -101,11 +107,29 @@ + static int mboxlist_changequota(const char *name, int matchlen, int maycreate, + void *rock); + ++static int mboxlist_autochangesub(char *name, int matchlen, int maycreate, ++ void *rock); ++ ++static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace, ++ char *userid, char *auth_userid, ++ struct auth_state *auth_state); ++ + struct change_rock { + struct quota *quota; + struct txn **tid; + }; + ++/* ++ * Struct needed to be passed as void *rock to ++ * mboxlist_autochangesub(); ++ */ ++struct changesub_rock_st { ++ char *userid; ++ char *auth_userid; ++ struct auth_state *auth_state; ++}; ++ ++ + #define FNAME_SUBSSUFFIX ".sub" + + /* +@@ -3380,3 +3404,349 @@ + + return(config_delete_mode == IMAP_ENUM_DELETE_MODE_DELAYED); + } ++ ++/* ++ * Automatically subscribe user to *ALL* shared folders, ++ * one has permissions to be subscribed to. ++ * INBOX subfolders are excluded. ++ */ ++static int mboxlist_autochangesub(char *name, int matchlen, int maycreate, ++ void *rock) { ++ ++ struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock; ++ char *userid = changesub_rock->userid; ++ char *auth_userid = changesub_rock->auth_userid; ++ struct auth_state *auth_state = changesub_rock->auth_state; ++ int r; ++ ++ ++ if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */ ++ (strlen(name) > 5 && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */ ++ (strlen(name) > 4 && !strncmp(name, "user.", 5))) /* Exclude other users' folders */ ++ return 0; ++ ++ ++ r = mboxlist_changesub(name, userid, auth_state, 1, 0); ++ ++ if (r) { ++ syslog(LOG_WARNING, ++ "autosubscribe: User %s to folder %s, subscription failed: %s", ++ auth_userid, name, error_message(r)); ++ } else { ++ syslog(LOG_NOTICE, ++ "autosubscribe: User %s to folder %s, subscription succeeded", ++ auth_userid, name); ++ } ++ ++ return 0; ++} ++ ++#define SEP '|' ++ ++/* ++ * Automatically subscribe user to a shared folder. ++ * Subscription is done successfully, if the shared ++ * folder exists and the user has the necessary ++ * permissions. ++ */ ++static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace, ++ char *userid, char *auth_userid, ++ struct auth_state *auth_state) { ++ ++ const char *sub ; ++ char *p, *q, *next_sub; ++ char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1]; ++ int len; ++ int r = 0; ++ int subscribe_all_sharedfolders = 0; ++ ++ subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS); ++ ++ /* ++ * If subscribeallsharedfolders is set to yes in imapd.conf, then ++ * subscribe user to every shared folder one has the apropriate ++ * permissions. ++ */ ++ if(subscribe_all_sharedfolders) { ++ char pattern[MAX_MAILBOX_PATH+1]; ++ struct changesub_rock_st changesub_rock; ++ ++ strcpy(pattern, "*"); ++ changesub_rock.userid = userid; ++ changesub_rock.auth_userid = auth_userid; ++ changesub_rock.auth_state = auth_state; ++ ++ r = mboxlist_findall(namespace, pattern, 0, userid, ++ auth_state, mboxlist_autochangesub, &changesub_rock); ++ ++ return r; ++ } ++ ++ if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL) ++ return r; ++ ++ next_sub = (char *) sub; ++ while (*next_sub) { ++ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++); ++ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++); ++ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--); ++ if (!*p ) continue; ++ ++ len = q - p + 1; ++ /* Check for folder length */ ++ if (len > sizeof(folder)-1) ++ continue; ++ ++ if (!r) { ++ strncpy(folder, p, len); ++ folder[len] = '\0'; ++ ++ strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name)); ++ len = strlcat(name, folder, sizeof(name)); ++ ++ r = (namespace->mboxname_tointernal) (namespace, name, userid, ++ mailboxname); ++ } ++ ++ if (!r) ++ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0); ++ ++ if (!r) { ++ syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded", ++ userid, folder); ++ } else { ++ syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s", ++ userid, folder, error_message(r)); ++ r = 0; ++ } ++ } ++ ++ return r; ++} ++ ++ ++ ++int mboxlist_autocreateinbox(struct namespace *namespace, ++ char *userid, ++ struct auth_state *auth_state, ++ char *mailboxname, int autocreatequota) { ++ char name [MAX_MAILBOX_NAME+1]; ++ char folder [MAX_MAILBOX_NAME+1]; ++ char *auth_userid = NULL; ++ char *partition = NULL; ++ const char *crt; ++ const char *sub; ++ char *p, *q, *next_crt, *next_sub; ++ int len; ++ int r = 0; ++ int numcrt = 0; ++ int numsub = 0; ++#ifdef USE_SIEVE ++ const char *source_script; ++#endif ++ ++ ++ ++ auth_userid = auth_canonuser(auth_state); ++ if (auth_userid == NULL) { ++ /* ++ * Couldn't get cannon userid ++ */ ++ syslog(LOG_ERR, ++ "autocreateinbox: Could not get canonified userid for user %s", userid); ++ return IMAP_PARTITION_UNKNOWN; ++ } ++ ++ /* Added this for debug information. */ ++ syslog(LOG_DEBUG, "autocreateinbox: autocreate inbox for user %s was called", auth_userid); ++ ++ /* ++ * While this is not needed for admins ++ * and imap_admins accounts, it would be ++ * better to separate *all* admins and ++ * proxyservers from normal accounts ++ * (accounts that have mailboxes). ++ * UOA Specific note(1): Even if we do not ++ * exclude these servers-classes here, ++ * UOA specific code, will neither return ++ * role, nor create INBOX, because none of these ++ * administrative accounts belong to the ++ * mailRecipient objectclass, or have imapPartition. ++ * UOA Specific note(2): Another good reason for doing ++ * this, is to prevent the code, from getting into ++ * cyrus_ldap.c because of the continues MSA logins to LMTPd. ++ */ ++ ++ /* ++ * admins and the coresponding imap ++ * service, had already been excluded. ++ */ ++ ++ /* ++ * Do we really need group membership ++ * for admins or service_admins? ++ */ ++ if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0; ++ ++ /* ++ * Do we really need group membership ++ * for proxyservers? ++ */ ++ if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0; ++ ++ /* ++ * Check if user belongs to the autocreate_users group. This option ++ * controls for whom the mailbox may be automatically created. Default ++ * value for this option is 'anyone'. So, if not declared, all mailboxes ++ * will be created. ++ */ ++ if (!global_authisa(auth_state, IMAPOPT_AUTOCREATE_USERS)) { ++ syslog(LOG_DEBUG, "autocreateinbox: User %s does not belong to the autocreate_users. No mailbox is created", ++ auth_userid); ++ return IMAP_MAILBOX_NONEXISTENT; ++ } ++ ++#if 0 ++ /* ++ * Get Partition info or return. ++ * (Here you should propably use ++ * you own "get_partition(char *userid)" ++ * function. Otherwise all new INBOXes will be ++ * created into whatever partition has been declared ++ * as default in your imapd.conf) ++ */ ++ ++ partition = get_partition(userid); ++ if (partition == NULL) { ++ /* ++ * Couldn't get partition info ++ */ ++ syslog(LOG_ERR, ++ "Could not get imapPartition info for user %s", userid); ++ return IMAP_PARTITION_UNKNOWN; ++ } ++#endif ++ ++ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, ++ 1, userid, auth_state, 0, 0, 0); ++ ++ if (!r && autocreatequota > 0) ++ r = mboxlist_setquota(mailboxname, autocreatequota, 0); ++ ++ if (!r) ++ r = mboxlist_changesub(mailboxname, userid, ++ auth_state, 1, 1); ++ ++ if (!r) { ++ syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s", ++ auth_userid, partition == NULL ? "default" : partition); ++ } else { ++ syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s", ++ auth_userid, error_message(r)); ++ } ++ ++#if 0 ++ /* Allocated from get_partition, and not needed any more */ ++ free_partition(partition); ++#endif ++ ++ if (r) return r; ++ ++ /* INBOX's subfolders */ ++ if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS))) ++ sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS); ++ ++ /* Roll through crt */ ++ next_crt = (char *) crt; ++ while (next_crt!=NULL && *next_crt) { ++ for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++); ++ for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++); ++ for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--); ++ ++ if (!*p) continue; ++ ++ len = q - p + 1; ++ ++ /* First time we check for length */ ++ if (len > sizeof(folder) - 5) ++ r = IMAP_MAILBOX_BADNAME; ++ ++ if (!r) { ++ strncpy(folder, p, len); ++ folder[len] = '\0'; ++ ++ strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name)); ++ len = strlcat(name, folder, sizeof(name)); ++ } ++ ++ if (!r) ++ r = (namespace->mboxname_tointernal) (namespace, name, userid, ++ mailboxname); ++ if (!r) ++ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, ++ 1, userid, auth_state, 0, 0, 0); ++ ++ if (!r) { ++ numcrt++; ++ syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.", ++ auth_userid, name); ++ } else { ++ syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s", ++ auth_userid, name, error_message(r)); ++ r=0; ++ continue; ++ } ++ ++ /* Roll through sub */ ++ next_sub = (char *) sub; ++ while (next_sub!=NULL && *next_sub) { ++ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++); ++ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++); ++ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--); ++ if (!*p ) continue; ++ ++ len = q - p + 1; ++ ++ if (len != strlen(folder) || strncmp(folder, p, len)) ++ continue; ++ ++ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1); ++ ++ if (!r) { ++ numsub++; ++ syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded", ++ auth_userid, name); ++ } else ++ syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to %s failed. %s", ++ auth_userid, name, error_message(r)); ++ ++ break; ++ } ++ } ++ ++ if (crt!=NULL && *crt) ++ syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d", ++ auth_userid, numcrt, numsub); ++ ++ /* ++ * Check if shared folders are available for subscription. ++ */ ++ mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state); ++ ++#ifdef USE_SIEVE ++ /* ++ * Here the autocreate sieve script feature is iniated from. ++ */ ++ source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT); ++ ++ if (source_script) { ++ if (!autoadd_sieve(userid, source_script)) ++ syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid); ++ else ++ syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid); ++ } ++#endif ++ ++ return r; ++} ++ +diff -Naur cyrus-imapd-2.3.11/imap/mboxlist.h cyrus-imapd-2.3.11-autocreate.uncompiled/imap/mboxlist.h +--- cyrus-imapd-2.3.11/imap/mboxlist.h 2007-11-27 17:31:29.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/mboxlist.h 2007-12-12 13:30:27.000000000 +0200 +@@ -211,4 +211,8 @@ + int mboxlist_abort(struct txn *tid); + + int mboxlist_delayed_delete_isenabled(void); ++int mboxlist_autocreateinbox(struct namespace *namespace,char *userid, ++ struct auth_state *auth_state, char *mailboxname, ++ int autocreatequota); ++ + #endif +diff -Naur cyrus-imapd-2.3.11/imap/pop3d.c cyrus-imapd-2.3.11-autocreate.uncompiled/imap/pop3d.c +--- cyrus-imapd-2.3.11/imap/pop3d.c 2007-11-26 22:23:06.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/imap/pop3d.c 2007-12-12 13:29:49.000000000 +0200 +@@ -159,6 +159,8 @@ + static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* */ + static void cmd_apop(char *response); + ++static int autocreate_inbox(char *inboxname, char *userid); ++ + static void cmd_auth(char *arg); + static void cmd_capa(void); + static void cmd_pass(char *pass); +@@ -1227,6 +1229,7 @@ + popd_userid = xstrdup(userbuf); + prot_printf(popd_out, "+OK Name is a valid mailbox\r\n"); + } ++ + } + + void cmd_pass(char *pass) +@@ -1525,6 +1528,43 @@ + } + + /* ++ * Autocreate Inbox and subfolders upon login ++ */ ++int autocreate_inbox(char *inboxname, char *auth_userid) ++{ ++ struct auth_state *auth_state; ++ int autocreatequota; ++ int r; ++ ++ if (inboxname == NULL || auth_userid == NULL) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ /* ++ * Exclude anonymous ++ */ ++ if (!strcmp(popd_userid, "anonymous")) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ /* ++ * Check for autocreatequota ++ */ ++ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ /* ++ * Exclude admin's accounts ++ */ ++ auth_state = auth_newstate(popd_userid); ++ if (global_authisa(auth_state, IMAPOPT_ADMINS)) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ r = mboxlist_autocreateinbox(&popd_namespace, auth_userid, ++ auth_state, inboxname, autocreatequota); ++ return r; ++} ++ ++ ++/* + * Complete the login process by opening and locking the user's inbox + */ + int openinbox(void) +@@ -1553,6 +1593,12 @@ + + if (!r) r = mboxlist_detail(inboxname, &type, NULL, NULL, + &server, &acl, NULL); ++ ++ /* Try once again after autocreate_inbox */ ++ if (r == IMAP_MAILBOX_NONEXISTENT && !(r = autocreate_inbox(inboxname, userid))) ++ r = mboxlist_detail(inboxname, &type, NULL, NULL, ++ &server, &acl, NULL); ++ + if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) && + (!acl || + !((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) { +diff -Naur cyrus-imapd-2.3.11/lib/auth.c cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth.c +--- cyrus-imapd-2.3.11/lib/auth.c 2006-11-30 19:11:22.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth.c 2007-12-12 13:29:49.000000000 +0200 +@@ -117,3 +117,11 @@ + + auth->freestate(auth_state); + } ++ ++char *auth_canonuser(struct auth_state *auth_state) ++{ ++ struct auth_mech *auth = auth_fromname(); ++ ++ return auth->auth_canonuser(auth_state); ++} ++ +diff -Naur cyrus-imapd-2.3.11/lib/auth.h cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth.h +--- cyrus-imapd-2.3.11/lib/auth.h 2006-11-30 19:11:22.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth.h 2007-12-12 13:29:49.000000000 +0200 +@@ -54,6 +54,7 @@ + const char *identifier); + struct auth_state *(*newstate)(const char *identifier); + void (*freestate)(struct auth_state *auth_state); ++ char *(*auth_canonuser)(struct auth_state *auth_state); + }; + + extern struct auth_mech *auth_mechs[]; +@@ -76,5 +77,6 @@ + const char *identifier); + struct auth_state *auth_newstate(const char *identifier); + void auth_freestate(struct auth_state *auth_state); ++char *auth_canonuser(struct auth_state *auth_state); + + #endif /* INCLUDED_AUTH_H */ +diff -Naur cyrus-imapd-2.3.11/lib/auth_krb.c cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_krb.c +--- cyrus-imapd-2.3.11/lib/auth_krb.c 2007-09-27 23:02:45.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_krb.c 2007-12-12 13:29:49.000000000 +0200 +@@ -338,6 +338,15 @@ + free((char *)auth_state); + } + ++static char *mycanonuser(struct auth_state *auth_state) ++{ ++ if (auth_state) ++ return auth_state->userid; ++ ++ return NULL; ++} ++ ++ + #else /* HAVE_KRB */ + + static int mymemberof( +@@ -369,6 +378,13 @@ + fatal("Authentication mechanism (krb) not compiled in", EC_CONFIG); + } + ++static char *mycanonuser( ++ struct auth_state *auth_state __attribute__((unused))) ++{ ++ fatal("Authentication mechanism (krb) not compiled in", EC_CONFIG); ++} ++ ++ + #endif + + struct auth_mech auth_krb = +@@ -379,4 +395,5 @@ + &mymemberof, + &mynewstate, + &myfreestate, ++ &mycanonuser, + }; +diff -Naur cyrus-imapd-2.3.11/lib/auth_krb5.c cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_krb5.c +--- cyrus-imapd-2.3.11/lib/auth_krb5.c 2007-09-27 23:02:45.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_krb5.c 2007-12-12 13:29:49.000000000 +0200 +@@ -197,6 +197,14 @@ + free(auth_state); + } + ++static char *mycanonuser(struct auth_state *auth_state) ++{ ++ if (auth_state) ++ return auth_state->userid; ++ ++ return NULL; ++} ++ + #else /* HAVE_GSSAPI_H */ + + static int mymemberof( +@@ -228,6 +236,12 @@ + fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG); + } + ++static char *mycanonuser( ++ struct auth_state *auth_state __attribute__((unused))) ++{ ++ fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG); ++} ++ + #endif + + struct auth_mech auth_krb5 = +@@ -238,4 +252,5 @@ + &mymemberof, + &mynewstate, + &myfreestate, ++ &mycanonuser, + }; +diff -Naur cyrus-imapd-2.3.11/lib/auth_pts.c cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_pts.c +--- cyrus-imapd-2.3.11/lib/auth_pts.c 2007-09-27 23:02:45.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_pts.c 2007-12-12 13:29:49.000000000 +0200 +@@ -511,6 +511,14 @@ + free(auth_state); + } + ++static char *mycanonuser(struct auth_state *auth_state) ++{ ++ if (auth_state) ++ return auth_state->userid.id; ++ ++ return NULL; ++} ++ + struct auth_mech auth_pts = + { + "pts", /* name */ +@@ -519,4 +527,5 @@ + &mymemberof, + &mynewstate, + &myfreestate, ++ &mycanonuser, + }; +diff -Naur cyrus-imapd-2.3.11/lib/auth_unix.c cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_unix.c +--- cyrus-imapd-2.3.11/lib/auth_unix.c 2007-10-31 12:42:18.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/auth_unix.c 2007-12-12 13:29:49.000000000 +0200 +@@ -314,6 +314,16 @@ + free((char *)auth_state); + } + ++static char *mycanonuser(auth_state) ++ struct auth_state *auth_state; ++{ ++ if (auth_state) ++ return auth_state->userid; ++ ++ return NULL; ++} ++ ++ + + struct auth_mech auth_unix = + { +@@ -323,4 +333,5 @@ + &mymemberof, + &mynewstate, + &myfreestate, ++ &mycanonuser, + }; +diff -Naur cyrus-imapd-2.3.11/lib/imapoptions cyrus-imapd-2.3.11-autocreate.uncompiled/lib/imapoptions +--- cyrus-imapd-2.3.11/lib/imapoptions 2007-10-18 21:14:48.000000000 +0300 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/lib/imapoptions 2007-12-12 13:29:49.000000000 +0200 +@@ -177,6 +177,55 @@ + /* Number of seconds to wait before returning a timeout failure when + performing a client connection (e.g. in a murder environment) */ + ++{ "createonpost", 0, SWITCH } ++/* If yes, when lmtpd receives an incoming mail for an INBOX that does not exist, ++ then the INBOX is automatically created by lmtpd. */ ++ ++{ "autocreateinboxfolders", NULL, STRING } ++/* If a user does not have an INBOX created then the INBOX as well as some INBOX ++ subfolders are created under two conditions. ++ 1. The user logins via the IMAP or the POP3 protocol. (autocreatequota option must have a nonzero value) ++ 2. A message arrives for the user through the LMTPD protocol.(createonpost option must be yes) ++ autocreateinboxfolders is a list of INBOX's subfolders separated by a "|", that ++ are automatically created by the server under the previous two situations. */ ++ ++{ "autosubscribeinboxfolders", NULL, STRING } ++/* A list of folder names, separated by "|", that the users get automatically subscribed to, ++ when their INBOX is created. These folder names must have been included in the ++ autocreateinboxfolders option of the imapd.conf. */ ++ ++{ "autosubscribesharedfolders", NULL, STRING } ++/* A list of shared folders (bulletin boards), separated by "|", that the users get ++ automatically subscribed to, after their INBOX is created. The shared folder must ++ have been created and the user must have the required permissions to get subscribed ++ to it. Otherwise, subscribing to the shared folder fails. */ ++ ++{ "autosubscribe_all_sharedfolders", 0, SWITCH } ++/* If set to yes, the user is automatically subscribed to all shared folders, one has permission ++ to subscribe to. */ ++ ++{ "autocreate_sieve_script", NULL, STRING } ++/* The full path of a file that contains a sieve script. This script automatically becomes a ++ user's initial default sieve filter script. When this option is not defined, no default ++ sieve filter is created. The file must be readable by the cyrus daemon. */ ++ ++{ "autocreate_sieve_compiledscript", NULL, STRING } ++/* The full path of a file that contains a compiled in bytecode sieve script. This script ++ automatically becomes a user's initial default sieve filter script. If this option is ++ not specified, or the filename doesn't exist then the script defined by ++ autocreate_sieve_script is compiled on the fly and installed as the user's default ++ sieve script */ ++ ++{ "generate_compiled_sieve_script", 0, SWITCH } ++/* If set to yes and no compiled sieve script file exists, the sieve script which is ++ compiled on the fly will be saved in the file name that autocreate_sieve_compiledscript ++ option points to. In order a compiled script to be generated, autocreate_sieve_script and ++ autocreate_sieve_compiledscript must have valid values */ ++ ++{ "autocreate_users", "anyone", STRING } ++/* A space separated list of users and/or groups that are allowed their INBOX to be ++ automatically created. */ ++ + { "configdirectory", NULL, STRING } + /* The pathname of the IMAP configuration directory. This field is + required. */ +diff -Naur cyrus-imapd-2.3.11/notifyd/Makefile.in cyrus-imapd-2.3.11-autocreate.uncompiled/notifyd/Makefile.in +--- cyrus-imapd-2.3.11/notifyd/Makefile.in 2006-11-30 19:11:23.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/notifyd/Makefile.in 2007-12-12 13:29:49.000000000 +0200 +@@ -69,10 +69,11 @@ + SERVICE=../master/service.o + + IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@ ++SIEVE_LIBS = @SIEVE_LIBS@ + IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@ + LIB_WRAP = @LIB_WRAP@ + LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS) +-DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ ++DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ + + PURIFY=/usr/local/bin/purify + PUREOPT=-best-effort +diff -Naur cyrus-imapd-2.3.11/notifyd/notifyd.c cyrus-imapd-2.3.11-autocreate.uncompiled/notifyd/notifyd.c +--- cyrus-imapd-2.3.11/notifyd/notifyd.c 2006-11-30 19:11:23.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/notifyd/notifyd.c 2007-12-12 13:29:49.000000000 +0200 +@@ -97,7 +97,7 @@ + + #define NOTIFY_MAXSIZE 8192 + +-int do_notify() ++static int do_notify() + { + struct sockaddr_un sun_data; + socklen_t sunlen = sizeof(sun_data); +diff -Naur cyrus-imapd-2.3.11/ptclient/Makefile.in cyrus-imapd-2.3.11-autocreate.uncompiled/ptclient/Makefile.in +--- cyrus-imapd-2.3.11/ptclient/Makefile.in 2006-11-30 19:11:24.000000000 +0200 ++++ cyrus-imapd-2.3.11-autocreate.uncompiled/ptclient/Makefile.in 2007-12-12 13:29:49.000000000 +0200 +@@ -57,10 +57,11 @@ + AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@ + AFS_LIBS = @AFS_LIBS@ + IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@ ++SIEVE_LIBS = @SIEVE_LIBS@ + LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@ + LIB_SASL = @LIB_SASL@ + LIB_WRAP = @LIB_WRAP@ +-DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ ++DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ + UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o + + LDAP_LIBS=@LDAP_LIBS@ diff --git a/cyrus-imapd-2.3.11-autosieve-0.6.0.diff b/cyrus-imapd-2.3.11-autosieve-0.6.0.diff new file mode 100644 index 0000000..b9fe0c4 --- /dev/null +++ b/cyrus-imapd-2.3.11-autosieve-0.6.0.diff @@ -0,0 +1,181 @@ +diff -Naur cyrus-imapd-2.3.11/README.autosievefolder cyrus-imapd-2.3.11-autosieve.uncompiled/README.autosievefolder +--- cyrus-imapd-2.3.11/README.autosievefolder 1970-01-01 02:00:00.000000000 +0200 ++++ cyrus-imapd-2.3.11-autosieve.uncompiled/README.autosievefolder 2007-12-12 14:17:18.000000000 +0200 +@@ -0,0 +1,42 @@ ++Cyrus IMAP autosievefolder patch ++---------------------------------- ++ ++NOTE : This patch has been created at the University of Athens. For more info, as well ++as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr ++ ++ ++ When the lmtpd daemon receives an email message prior to delivering it to the ++INBOX folder of the user, checks if the user has specified sieve filters. If the ++user has specified sieve filters the filters are evaluated. If the message matches ++any of the filters the action that is specified in the filter is executed. If the action ++is FileInto it is stored in the subfolder specified in the filter. If the ++subfolder doesn't exist then the message is sent to the INBOX folder of the user. ++ ++ With this patch if the folder doesn't exist AND the name of the subfolder is ++specified in the autosievefolders option, OR the anysievefolder is set to ++yes in the cyrus-imap configuration file then the subfolder is created and the mail ++is stored there. ++ ++ ++Check the following options of the imapd.conf file ++================================================== ++ ++* anysievefolder : It must be "yes" in order to permit the autocreation of any ++INBOX subfolder requested by a sieve filter, through the "fileinto" action. (default = no) ++* autosievefolders : It is a "|" separated list of subfolders of INBOX that will be ++automatically created, if requested by a sieve filter, through the "fileinto" ++action. (default = null) ++ i.e. autosievefolders: Junk | Spam ++ ++WARNING: anysievefolder, takes precedence over autosievefolders . Which means that if ++anysievefolder is set to "yes", cyrus will create any INBOX subfolder requested, no-matter what the value of autosievefolders is. ++ ++ ++Things to be done ++================= ++ ++1. Support cyrus wildcards in the autosievefolders option. ++ ++ ++For more information and updates please visit http://email.uoa.gr/projects/cyrus/autosievefolder ++ +diff -Naur cyrus-imapd-2.3.11/imap/lmtp_sieve.c cyrus-imapd-2.3.11-autosieve.uncompiled/imap/lmtp_sieve.c +--- cyrus-imapd-2.3.11/imap/lmtp_sieve.c 2007-09-28 05:27:46.000000000 +0300 ++++ cyrus-imapd-2.3.11-autosieve.uncompiled/imap/lmtp_sieve.c 2007-12-12 14:17:18.000000000 +0200 +@@ -88,6 +88,9 @@ + struct auth_state *authstate; + } script_data_t; + ++static int autosieve_subfolder(char *userid, struct auth_state *auth_state, ++ char *subfolder, struct namespace *namespace); ++ + static char *make_sieve_db(const char *user) + { + static char buf[MAX_MAILBOX_PATH+1]; +@@ -484,7 +487,20 @@ + sd->username, mdata->notifyheader, + namebuf, quotaoverride, 0); + } +- ++ ++ if (ret == IMAP_MAILBOX_NONEXISTENT) { ++ /* if "plus" folder under INBOX, then try to create it */ ++ ret = autosieve_subfolder((char *) sd->username, sd->authstate, namebuf, mdata->namespace); ++ ++ /* Try to deliver the mail again. */ ++ if (!ret) ++ ret = deliver_mailbox(md->f, mdata->content, mdata->stage, md->size, ++ fc->imapflags->flag, fc->imapflags->nflags, ++ (char *) sd->username, sd->authstate, md->id, ++ sd->username, mdata->notifyheader, ++ namebuf, quotaoverride, 0); ++ } ++ + if (!ret) { + snmp_increment(SIEVE_FILEINTO, 1); + return SIEVE_OK; +@@ -935,3 +951,80 @@ + we'll do normal delivery */ + return r; + } ++ ++ ++#define SEP '|' ++ ++static int autosieve_subfolder(char *userid, struct auth_state *auth_state, ++ char *subfolder, struct namespace *namespace) ++{ ++ char option_name_external[MAX_MAILBOX_NAME + 1]; ++ char option_name_internal[MAX_MAILBOX_NAME + 1]; ++ const char *subf ; ++ char *p, *q, *next_subf; ++ int len, r = 0; ++ int createsievefolder = 0; ++ ++ /* Check if subfolder or userid are NULL */ ++ if(userid == NULL || subfolder == NULL) ++ return IMAP_MAILBOX_NONEXISTENT; ++ ++ syslog(LOG_DEBUG, "autosievefolder: autosieve_subfolder() was called for user %s, folder %s", ++ userid, subfolder); ++ ++ if (config_getswitch(IMAPOPT_ANYSIEVEFOLDER)) { ++ createsievefolder = 1; ++ } else if ((subf = config_getstring(IMAPOPT_AUTOSIEVEFOLDERS)) != NULL) { ++ /* Roll through subf */ ++ next_subf = (char *) subf; ++ while (*next_subf) { ++ for (p = next_subf ; isspace((int) *p) || *p == SEP ; p++); ++ for (next_subf = p ; *next_subf && *next_subf != SEP ; next_subf++); ++ for (q = next_subf ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--); ++ ++ if (!*p) continue; ++ ++ len = q - p + 1; ++ /* ++ * This is a preliminary length check based on the assumption ++ * that the *final* internal format will be something ++ * like user.userid.subfolder(s). ++ */ ++ if (len > sizeof(option_name_external) - strlen(userid) - 5) ++ return IMAP_MAILBOX_BADNAME; ++ ++ strlcpy(option_name_external, namespace->prefix[NAMESPACE_INBOX], sizeof(option_name_external)); ++ strncat(option_name_external, p, len); ++ ++ /* ++ * Transform the option folder name to internal namespace and compare it ++ * with what must be created. ++ */ ++ r = namespace->mboxname_tointernal(namespace, option_name_external, userid, option_name_internal); ++ if (r) continue; ++ ++ if (!strcmp(option_name_internal, subfolder)) { ++ createsievefolder = 1; ++ break; ++ } ++ } ++ } ++ ++ if (createsievefolder) { ++ /* Folder is already in internal namespace format */ ++ r = mboxlist_createmailbox(subfolder, MAILBOX_FORMAT_NORMAL, NULL, ++ 1, userid, auth_state, 0, 0, 0); ++ if (!r) { ++ mboxlist_changesub(subfolder, userid, auth_state, 1, 1); ++ syslog(LOG_DEBUG, "autosievefolder: User %s, folder %s creation succeeded", ++ userid, subfolder); ++ return 0; ++ } else { ++ syslog(LOG_ERR, "autosievefolder: User %s, folder %s creation failed. %s", ++ userid, subfolder,error_message(r)); ++ return r; ++ } ++ } else ++ return IMAP_MAILBOX_NONEXISTENT; ++} ++ +diff -Naur cyrus-imapd-2.3.11/lib/imapoptions cyrus-imapd-2.3.11-autosieve.uncompiled/lib/imapoptions +--- cyrus-imapd-2.3.11/lib/imapoptions 2007-10-18 21:14:48.000000000 +0300 ++++ cyrus-imapd-2.3.11-autosieve.uncompiled/lib/imapoptions 2007-12-12 14:17:18.000000000 +0200 +@@ -906,6 +906,15 @@ + /* If enabled, lmtpd will look for Sieve scripts in user's home + directories: ~user/.sieve. */ + ++{ "anysievefolder", 0, SWITCH } ++/* It must be "yes" in order to permit the autocreation of any INBOX subfolder ++ requested by a sieve filter, through the "fileinto" action. (default = no) */ ++ ++{ "autosievefolders", NULL, STRING } ++/* It is a "|" separated list of subfolders of INBOX that will be automatically created, ++ if requested by a sieve filter, through the "fileinto" action. (default = null) ++ i.e. autosievefolders: Junk | Spam */ ++ + { "singleinstancestore", 1, SWITCH } + /* If enabled, imapd, lmtpd and nntpd attempt to only write one copy + of a message per partition and create hard links, resulting in a diff --git a/cyrus-imapd-2.3.9-autocreate-0.10-0.diff b/cyrus-imapd-2.3.9-autocreate-0.10-0.diff deleted file mode 100644 index 12b4abd..0000000 --- a/cyrus-imapd-2.3.9-autocreate-0.10-0.diff +++ /dev/null @@ -1,2374 +0,0 @@ -diff -Naur cyrus-imapd-2.3.9/README.autocreate cyrus-imapd-2.3.9-autocreate.uncompiled/README.autocreate ---- cyrus-imapd-2.3.9/README.autocreate 1970-01-01 02:00:00.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/README.autocreate 2007-08-21 14:59:22.000000000 +0300 -@@ -0,0 +1,211 @@ -+Cyrus IMAP autocreate Inbox patch -+---------------------------------- -+ -+NOTE : This patch has been created at the University of Athens. For more info, as well -+as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr/ -+ -+The design of Cyrus IMAP server does not predict the automatic creation of users' -+INBOX folders. The creation of a user's INBOX is considered to be an external task, -+that has to be completed as part of the user email account creation procedure. -+Hence, to create a new email account the site administrator has to: -+ -+ a) Include the new account in the user database for the authentication procedure -+ (e.g. sasldb, shadow, mysql, ldap). -+ b) Create the corresponding INBOX folder. -+ -+Alternatively, the user, if succesfully authenticated, may create his own INBOX folder, -+as long as the configuration of the site allows it (see "autocreatequota" in imapd.conf). -+Unlike what not careful readers may think, enabling the "autocreatequota" option, doesn't -+lead to the automatic INBOX folder creation by Cyrus IMAP server. -+In fact, "autocreate" means that the IMAP clients are allowed to automatically create -+the user INBOX. -+ -+This patch adds the functionality of automatic creation of the users' INBOX folders into -+the Cyrus IMAP server. It is implemented as two features, namely the "create on login" -+and "create on post". -+ -+ -+ -+Create on login -+=============== -+This feauture provides automatic creation of a user's INBOX folder when all of the -+following requirements are met: -+ -+i) The user has succesfully passed the authentication procedure. -+ -+ii) The user's authorisation ID (typically the same as the user's -+authentication ID) doesn't belong to the imap_admins or admins -+accounts (see imapd.conf). -+ -+iii) The "autocreatequota" option in the imap configuration file -+has been set to a non zero value. -+ -+iv) The corresponding to the user's authorisation ID INBOX folder -+does not exist. -+ -+The user's first login is the most typical case when all four requirements are met. -+Note that if the authenticated ID is allowed to proxy to another account for which -+all of the above requirements are met, the corresponding INBOX folder for that account -+will be created. -+ -+ -+ -+Create on post -+============== -+This feauture provides automatic creation of a user's INBOX folder when all of the -+following requirements are met. -+ -+i) An email message addressed to the user has been received. -+ -+ii) The recipient is not any of the imap_admins or admins accounts. -+Note that passing emails to admins or imap_admins accounts from -+the MTA to LMTP should be avoided in any case. -+ -+iii) The recipient's INBOX does not exist. -+ -+iv) The "autocreatequota" option in the imap configuration file -+has been set to a non zero value. -+ -+v) The "createonpost" option in the imap configuration file -+has been switched on. -+ -+ -+Besides the automatic creation of INBOX folder, additional functionalities are -+provided: -+ -+ (A) Automatic creation of INBOX subfolders controlled by "autocreateinboxfolders" -+configuration option. eg -+ -+autocreateinboxfolders: sent|drafts|spam|templates -+ -+ (B) Automatic subscription of INBOX subfolders controlled by "autosubscribeinboxfolders" -+configuration option. eg -+ -+autosubscribeinboxfolders: sent|spam -+ -+Obviously, only subscription to subfolders included in the "autocreateinboxfolder" -+list is meaningful. -+ -+ (C) Automatic subscription to shared folders (bulletin boards). The user gets -+automatically subscribed to the shared folders declared in the "autosubscribesharedfolders" -+configuration option in imapd.conf. -+eg autosubscribesharedfolders: public_folder | public_folder.subfolder -+ -+In order the above action to succeed, the shared folder has to pre-exist the INBOX creation -+and the user must have the appropriate permissions in order to be able to subscribe to the -+shared folder. -+ -+* A new config option has been added. 'autosubscribe_all_sharedfolders' is a yes/no -+option. When set to yes, the user is automatically subscribed to all shared folders one -+has permission to subscribe to. Please, note that when this option is set to yes, then -+'autosubscribesharedfolders' option is overriden. -+ -+ (D) Automatic creation of a predefined default sieve script. -+ -+This is very useful when a default sieve script is used for every user. Usually, a -+default anti-spam script may me be written in a file and copied to each user -+sieve scripts upon the INBOX creation. The imapd.conf options that have been added -+are 'autocreate_sieve_script', 'autocreate_sieve_compiledscript' and -+'generate_compiled_sieve_script'. -+ -+autocreate_sieve_script configuration option refers to the full path of the file -+that contains the sieve script. The default value is null and if no file is defined, -+then no default script is created upon INBOX creation. (The feature is disabled) -+eg autocreate_sieve_script: /etc/default_sieve_script -+ -+autocreate_sieve_compiledscript configuration option refers to the full path of the -+file that contains the bytecode compiled sieve script. If this filename is defined -+in imapd.conf and the file exists, then it is automatically copied in the user's sieve -+directory. If it is not defined, then a bytecode sieve script gets on the fly compiled -+by the daemon. -+eg autocreate_sieve_compiledscript: /etc/default_sieve_script.bc -+ -+generate_compiled_sieve_script is a boolean option that triggers the compilation of the -+source sieve script to bytecode sieve script. The file that the bytecode script will -+be saved is pointed by autocreate_sieve_compiledscript. -+ -+Ways of compiling a sieve script : -+1. Compile a sieve script using the standard sievec utility, distributed by CMU -+2. Compile a sieve script using the compile_sieve utility, released by UoA. This -+ tool is almost identical to the sievec utility, with the difference that it -+ reads the input and output file from autocreate_sieve_script and -+ autocreate_sieve_compiledscript options in imapd.conf -+3. Let cyrus create a compiled sieve script using a source script. Cyrus can be -+ instructed to save the compiled script any time a compiled script does not exist. -+ -+NOTES : -+1. In order this functionality to work, the following requirements must have been met: -+ - 'sieveusehomedir' option must be 'no' in the configuration (default). -+ - 'sievedir' option must have a valid value. -+2. Currently, this patch checks the validity of the source script while generating a -+ bytecode compiled script, but not the validity of the bytecode sieve script file. -+ The administrator should make sure that the provided files contain a valid sieve -+ script as well as the compiled script is updated every time the source script changes. -+ -+ -+ (E) The administrator may control for which users and/or groups may the INBOXes -+automatically be created. The autocreate_users option restricts the groups -+for which the patch will create the mailboxes. -+ -+The default value of autocreate_users is anyone. So, if not set at all, the patch will -+work for all users. However, one may set: -+ -+autocreate_users: user1 user2 group:group1 group:group2 -+ -+In that case, the INBOX will be created only for user1, user2 and the users that belong -+to group1 and group2. -+ -+More refined control per service is provided by the options imap_autocreate_users, -+pop3_autocreate_users and lmtp_autocreate_users. These options override the -+autocreate_users option and offer per service control. -+ -+Example: -+One may want to restrict the create on post functionality only for a specific group -+of users. To achieve this, the following lines must be added in the imapd.conf file: -+ -+createonpost: yes -+lmtp_autocreate_users: group:groupname -+ -+ -+ -+Issues to be considered -+======================= -+ -+I) In order to use the create on post feauture one should be absolutely sure that: -+a) The MTA checks the validity of the email recipient before sending the email to -+LMTP. This is an RFC821 requirement. This usually expands to "the mta should be -+able to use the account database as user mailbox database". -+b) Only authorised accounts/services can talk to LMTP. -+ -+II) Especially in the case of imap logins, the current patch implementation checks -+for the INBOX folder existence upon login, causing an extra mailbox lookup in most -+of the cases. -+A better approach would be to chase the "IMAP_MAILBOX_NONEXISTENT" error code and -+check if the error is associated with an INBOX folder. However, this would mess up -+Cyrus code. The way it was implemented may not have been the most performance -+optimised, but it produces a much cleaner and simple patch. -+ -+ -+ -+Virtual Domains Support -+======================= -+ -+Virtual domains are supported by all versions of the patch for cyrus-imapd-2.2.1-BETA and -+later. However, it is not possible to declare different INBOX subfolders to be created or -+shared folders to be subscribed to for every domain. -+ -+ -+ -+Things to be done -+================= -+ -+1. Support MUPDATE -+ -+It is within the developers' intentions to support the mupdate protocol, but serious -+design issues on future cyrus releases have to resolved first. -+ -+2. Select different attributes (quota, partition, sieve filter, etc) depending on the group -+a user belongs to. -+ -+For more information and updates please visit http://email.uoa.gr/projects/cyrus/autocreate -+ -diff -Naur cyrus-imapd-2.3.9/imap/Makefile.in cyrus-imapd-2.3.9-autocreate.uncompiled/imap/Makefile.in ---- cyrus-imapd-2.3.9/imap/Makefile.in 2007-01-09 19:41:35.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/Makefile.in 2007-08-21 14:59:22.000000000 +0300 -@@ -101,7 +101,7 @@ - convert_code.o duplicate.o saslclient.o saslserver.o signals.o \ - annotate.o search_engines.o squat.o squat_internal.o mbdump.o \ - imapparse.o telemetry.o user.o notify.o protocol.o idle.o quota_db.o \ -- sync_log.o $(SEEN) mboxkey.o backend.o tls.o -+ sync_log.o autosieve.o $(SEEN) mboxkey.o backend.o tls.o - - IMAPDOBJS=pushstats.o imapd.o proxy.o imap_proxy.o index.o version.o - -@@ -117,7 +117,7 @@ - fud smmapd reconstruct quota mbpath ipurge cyr_dbtool \ - cyrdump chk_cyrus cvt_cyrusdb deliver ctl_mboxlist \ - ctl_deliver ctl_cyrusdb squatter mbexamine cyr_expire arbitron \ -- unexpunge @IMAP_PROGS@ -+ unexpunge compile_sieve @IMAP_PROGS@ - - BUILTSOURCES = imap_err.c imap_err.h pushstats.c pushstats.h \ - lmtpstats.c lmtpstats.h xversion.h mupdate_err.c mupdate_err.h \ -@@ -183,9 +183,9 @@ - mupdate_err.h: mupdate_err.c - - ### Services --idled: idled.o mutex_fake.o libimap.a $(DEPLIBS) -+idled: idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o idled \ -- idled.o mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) -+ idled.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - - lmtpd: lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) mutex_fake.o \ - libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) -@@ -199,151 +199,156 @@ - $(SERVICE) lmtpd.o proxy.o $(LMTPOBJS) $(SIEVE_OBJS) \ - mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - --imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) -+imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o imapd \ - $(SERVICE) $(IMAPDOBJS) mutex_fake.o \ -- libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - --imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) -+imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \ - $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - --imapd.quant: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) -+imapd.quant: $(IMAPDOBJS) mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(QUANTIFY) $(QUANTOPT) $(CC) $(LDFLAGS) -o imapd.quant \ - $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - - mupdate: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o tls.o \ -- libimap.a $(DEPLIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o mupdate \ - $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \ - mutex_pthread.o tls.o libimap.a \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread - - mupdate.pure: mupdate.o mupdate-slave.o mupdate-client.o mutex_pthread.o \ -- libimap.a $(DEPLIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o mupdate.pure \ - $(SERVICETHREAD) mupdate.o mupdate-slave.o mupdate-client.o \ -- mutex_pthread.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread -+ mutex_pthread.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) -lpthread - - pop3d: pop3d.o proxy.o backend.o tls.o mutex_fake.o libimap.a \ -- $(DEPLIBS) $(SERVICE) -+ $(DEPLIBS) $(SIEVE_LIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o pop3d pop3d.o proxy.o backend.o tls.o $(SERVICE) \ -- mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - - nntpd: nntpd.o proxy.o backend.o index.o smtpclient.o spool.o tls.o \ -- mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE) -+ mutex_fake.o nntp_err.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o nntpd nntpd.o proxy.o backend.o index.o spool.o \ - smtpclient.o tls.o $(SERVICE) mutex_fake.o nntp_err.o \ -- libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - --fud: fud.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) -+fud: fud.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o fud $(SERVICE) fud.o mutex_fake.o libimap.a \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - --smmapd: smmapd.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) -+smmapd: smmapd.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o smmapd $(SERVICE) smmapd.o mutex_fake.o libimap.a \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - - sync_server: sync_server.o sync_support.o sync_commit.o \ -- imapparse.o tls.o libimap.a mutex_fake.o $(DEPLIBS) $(SERVICE) -+ imapparse.o tls.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(SERVICE) - $(CC) $(LDFLAGS) -o \ - sync_server sync_server.o sync_support.o sync_commit.o \ - imapparse.o tls.o $(SERVICE) libimap.a mutex_fake.o \ -- $(DEPLIBS) $(LIBS) $(LIB_WRAP) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) $(LIB_WRAP) - - ### Command Line Utilities --arbitron: arbitron.o $(CLIOBJS) libimap.a $(DEPLIBS) -+arbitron: arbitron.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o arbitron arbitron.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --cyr_dbtool: cyr_dbtool.o mutex_fake.o libimap.a $(DEPLIBS) -+cyr_dbtool: cyr_dbtool.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o cyr_dbtool cyr_dbtool.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(DEPLIBS) -+cvt_cyrusdb: cvt_cyrusdb.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o cvt_cyrusdb cvt_cyrusdb.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(DEPLIBS) -+chk_cyrus: chk_cyrus.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o chk_cyrus chk_cyrus.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --deliver: deliver.o $(LMTPOBJS) proxy.o mutex_fake.o libimap.a $(DEPLIBS) -+deliver: deliver.o $(LMTPOBJS) proxy.o mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o deliver deliver.o $(LMTPOBJS) proxy.o \ -- mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) -+ mutex_fake.o libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) -+ctl_deliver: ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- $@ ctl_deliver.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ $@ ctl_deliver.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(DEPLIBS) -+ctl_mboxlist: ctl_mboxlist.o mupdate-client.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o $@ ctl_mboxlist.o mupdate-client.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) -+ctl_cyrusdb: ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ $@ ctl_cyrusdb.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(DEPLIBS) -+cyr_expire: cyr_expire.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o $@ cyr_expire.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) -+fetchnews: fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- $@ fetchnews.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ $@ fetchnews.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(DEPLIBS) -+squatter: squatter.o index.o squat_build.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o squatter squatter.o index.o squat_build.o \ -- $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --mbpath: mbpath.o $(CLIOBJS) libimap.a $(DEPLIBS) -+mbpath: mbpath.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o mbpath mbpath.o $(CLIOBJS) libimap.a \ -- $(DEPLIBS) $(LIBS) -+ $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --ipurge: ipurge.o $(CLIOBJS) libimap.a $(DEPLIBS) -+ipurge: ipurge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o ipurge ipurge.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(DEPLIBS) -+cyrdump: cyrdump.o index.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o cyrdump cyrdump.o index.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) -+mbexamine: mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- mbexamine mbexamine.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ mbexamine mbexamine.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) -+reconstruct: reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- reconstruct reconstruct.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ reconstruct reconstruct.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --quota: quota.o $(CLIOBJS) libimap.a $(DEPLIBS) -+quota: quota.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o quota quota.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) -+tls_prune: tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ -- $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(DEPLIBS) $(LIBS) -+ $@ tls_prune.o tls.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --unexpunge: unexpunge.o $(CLIOBJS) libimap.a $(DEPLIBS) -+unexpunge: unexpunge.o $(CLIOBJS) libimap.a $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o $@ unexpunge.o $(CLIOBJS) \ -- libimap.a $(DEPLIBS) $(LIBS) -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - --make_md5: make_md5.o libimap.a mutex_fake.o $(DEPLIBS) -- $(CC) $(LDFLAGS) -o make_md5 make_md5.o libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) -+make_md5: make_md5.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) -+ $(CC) $(LDFLAGS) -o make_md5 make_md5.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - - sync_client: sync_client.o sync_support.o \ -- backend.o tls.o imapparse.o libimap.a mutex_fake.o $(DEPLIBS) -+ backend.o tls.o imapparse.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ - sync_client sync_client.o sync_support.o \ -- backend.o tls.o imapparse.o libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) -+ backend.o tls.o imapparse.o libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) - - sync_reset: sync_reset.o sync_support.o sync_commit.o \ -- libimap.a mutex_fake.o $(DEPLIBS) -+ libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) - $(CC) $(LDFLAGS) -o \ - sync_reset sync_reset.o sync_support.o sync_commit.o \ -- libimap.a mutex_fake.o $(DEPLIBS) $(LIBS) -+ libimap.a mutex_fake.o $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) -+ -+compile_sieve: compile_sieve.o libimap.a $(DEPLIBS) $(SIEVE_LIBS) -+ $(CC) $(LDFLAGS) -o compile_sieve compile_sieve.o $(CLIOBJS) \ -+ libimap.a $(SIEVE_LIBS) $(DEPLIBS) $(LIBS) -+ - - ### Other Misc Targets - -diff -Naur cyrus-imapd-2.3.9/imap/autosieve.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/autosieve.c ---- cyrus-imapd-2.3.9/imap/autosieve.c 1970-01-01 02:00:00.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/autosieve.c 2007-08-21 15:00:04.000000000 +0300 -@@ -0,0 +1,587 @@ -+#include -+#include -+#include -+ -+#ifdef HAVE_UNISTD_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "global.h" -+#include "util.h" -+#include "mailbox.h" -+#include "imap_err.h" -+#include "sieve_interface.h" -+#include "script.h" -+ -+#define TIMSIEVE_FAIL -1 -+#define TIMSIEVE_OK 0 -+#define MAX_FILENAME 1024 -+ -+static int get_script_name(char *sievename, size_t buflen, const char *filename); -+static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir); -+int autoadd_sieve(char *userid, const char *source_script); -+ -+static void fatal(const char *s, int code); -+static void foo(void); -+static int sieve_notify(void *ac __attribute__((unused)), -+ void *interp_context __attribute__((unused)), -+ void *script_context __attribute__((unused)), -+ void *message_context __attribute__((unused)), -+ const char **errmsg __attribute__((unused))); -+static int mysieve_error(int lineno, const char *msg, -+ void *i __attribute__((unused)), void *s); -+static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret); -+ -+ -+sieve_vacation_t vacation2 = { -+ 0, /* min response */ -+ 0, /* max response */ -+ (sieve_callback *) &foo, /* autorespond() */ -+ (sieve_callback *) &foo /* send_response() */ -+}; -+ -+ -+/* -+ * Find the name of the sieve script -+ * given the source script and compiled script names -+ */ -+static int get_script_name(char *sievename, size_t buflen, const char *filename) -+{ -+ char *p; -+ int r; -+ -+ p = strrchr(filename, '/'); -+ if (p == NULL) -+ p = (char *) filename; -+ else -+ p++; -+ -+ r = strlcpy(sievename, p, buflen) - buflen; -+ return (r >= 0 || r == -buflen ? 1 : 0); -+} -+ -+ -+/* -+ * Find the directory where the sieve scripts of the user -+ * reside -+ */ -+static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir) -+{ -+ char *user = NULL, *domain = NULL; -+ -+ /* Setup the user and the domain */ -+ if(config_virtdomains && (domain = strchr(userid, '@'))) { -+ user = (char *) xmalloc((domain - userid +1) * sizeof(char)); -+ strlcpy(user, userid, domain - userid + 1); -+ domain++; -+ } else -+ user = userid; -+ -+ /* Find the dir path where the sieve scripts of the user will reside */ -+ if (config_virtdomains && domain) { -+ if(snprintf(sieve_script_dir, buflen, "%s%s%c/%s/%c/%s/", -+ sieve_dir, FNAME_DOMAINDIR, dir_hash_c(domain, config_fulldirhash), domain, dir_hash_c(user,config_fulldirhash), user) >= buflen) { -+ free(user); -+ return 1; -+ } -+ } else { -+ if(snprintf(sieve_script_dir, buflen, "%s/%c/%s/", -+ sieve_dir, dir_hash_c(user,config_fulldirhash), user) >= buflen) -+ return 1; -+ } -+ -+ /* Free the xmalloced user memory, reserved above */ -+ if(user != userid) -+ free(user); -+ -+ return 0; -+} -+ -+int autoadd_sieve(char *userid, const char *source_script) -+{ -+ sieve_script_t *s = NULL; -+ bytecode_info_t *bc = NULL; -+ char *err = NULL; -+ FILE *in_stream, *out_fp; -+ int out_fd, in_fd, r, k; -+ int do_compile = 0; -+ const char *sieve_dir = NULL; -+ const char *compiled_source_script = NULL; -+ char sievename[MAX_FILENAME]; -+ char sieve_script_name[MAX_FILENAME]; -+ char sieve_script_dir[MAX_FILENAME]; -+ char sieve_bcscript_name[MAX_FILENAME]; -+ char sieve_default[MAX_FILENAME]; -+ char sieve_tmpname[MAX_FILENAME]; -+ char sieve_bctmpname[MAX_FILENAME]; -+ char sieve_bclink_name[MAX_FILENAME]; -+ char buf[4096]; -+ mode_t oldmask; -+ struct stat statbuf; -+ -+ /* We don't support using the homedirectory, like timsieved */ -+ if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) { -+ syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf"); -+ return 1; -+ } -+ -+ /* Check if sievedir is defined in imapd.conf */ -+ if(!(sieve_dir = config_getstring(IMAPOPT_SIEVEDIR))) { -+ syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf"); -+ return 1; -+ } -+ -+ /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */ -+ if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) { -+ syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it"); -+ do_compile = 1; -+ } -+ -+ if(get_script_dir(sieve_script_dir, sizeof(sieve_script_dir), userid, sieve_dir)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Cannot find sieve scripts directory"); -+ return 1; -+ } -+ -+ if (get_script_name(sievename, sizeof(sievename), source_script)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve script %s", source_script); -+ return 1; -+ } -+ -+ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s%s.script.NEW",sieve_script_dir, sievename) >= sizeof(sieve_tmpname)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ if(snprintf(sieve_bctmpname, sizeof(sieve_bctmpname), "%s%s.bc.NEW",sieve_script_dir, sievename) >= sizeof(sieve_bctmpname)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ if(snprintf(sieve_script_name, sizeof(sieve_script_name), "%s%s.script",sieve_script_dir, sievename) >= sizeof(sieve_script_name)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ if(snprintf(sieve_bcscript_name, sizeof(sieve_bcscript_name), "%s%s.bc",sieve_script_dir, sievename) >= sizeof(sieve_bcscript_name)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ if(snprintf(sieve_default, sizeof(sieve_default), "%s%s",sieve_script_dir,"defaultbc") >= sizeof(sieve_default)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ if(snprintf(sieve_bclink_name, sizeof(sieve_bclink_name), "%s.bc", sievename) >= sizeof(sieve_bclink_name)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_dir, sievename, userid); -+ return 1; -+ } -+ -+ /* Check if a default sieve filter alrady exists */ -+ if(!stat(sieve_default,&statbuf)) { -+ syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists"); -+ fclose(in_stream); -+ return 1; -+ } -+ -+ /* Open the source script. if there is a problem with that exit */ -+ in_stream = fopen(source_script, "r"); -+ if(!in_stream) { -+ syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script); -+ return 1; -+ } -+ -+ -+ /* -+ * At this point we start the modifications of the filesystem -+ */ -+ -+ /* Create the directory where the sieve scripts will reside */ -+ r = cyrus_mkdir(sieve_script_dir, 0755); -+ if(r == -1) { -+ /* If this fails we just leave */ -+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create directory %s. Check permissions",sieve_script_name); -+ return 1; -+ } -+ -+ /* -+ * We open the file that will be used as the bc file. If this file exists, overwrite it -+ * since something bad has happened. We open the file here so that this error checking is -+ * done before we try to open the rest of the files to start copying etc. -+ */ -+ out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); -+ if(out_fd < 0) { -+ if(errno == EEXIST) { -+ syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname); -+ } else if (errno == EACCES) { -+ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname); -+ fclose(in_stream); -+ return 1; -+ } else { -+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s. Unknown error",sieve_bctmpname); -+ fclose(in_stream); -+ return 1; -+ } -+ } -+ -+ if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) { -+ while((r = read(in_fd, buf, sizeof(buf))) > 0) { -+ if((k=write(out_fd, buf,r)) < 0) { -+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_bctmpname, errno); -+ close(out_fd); -+ close(in_fd); -+ fclose(in_stream); -+ unlink(sieve_bctmpname); -+ return 1; -+ } -+ } -+ -+ if(r == 0) { /* EOF */ -+ close(out_fd); -+ close(in_fd); -+ } else if (r < 0) { -+ syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file: %s. Will try to compile it", -+ compiled_source_script); -+ close(in_fd); -+ do_compile = 1; -+ if(lseek(out_fd, 0, SEEK_SET)) { -+ syslog(LOG_WARNING, "autocreate_sieve: Major IO problem. Aborting"); -+ return 1; -+ } -+ } -+ close(in_fd); -+ } else { -+ if(compiled_source_script) -+ syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script); -+ do_compile = 1; -+ } -+ -+ -+ /* Because we failed to open a precompiled bc sieve script, we compile one */ -+ if(do_compile) { -+ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) { -+ if(err && *err) { -+ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err); -+ free(err); -+ } else -+ syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script"); -+ -+ unlink(sieve_bctmpname); -+ fclose(in_stream); -+ close(out_fd); -+ return 1; -+ } -+ -+ /* generate the bytecode */ -+ if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) { -+ syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script"); -+ /* removing the copied script and cleaning up memory */ -+ unlink(sieve_bctmpname); -+ sieve_script_free(&s); -+ fclose(in_stream); -+ close(out_fd); -+ return 1; -+ } -+ -+ if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) { -+ syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script"); -+ /* removing the copied script and cleaning up memory */ -+ unlink(sieve_bctmpname); -+ sieve_free_bytecode(&bc); -+ sieve_script_free(&s); -+ fclose(in_stream); -+ close(out_fd); -+ return 1; -+ } -+ -+ /* clean up the memory */ -+ sieve_free_bytecode(&bc); -+ sieve_script_free(&s); -+ } -+ -+ close(out_fd); -+ rewind(in_stream); -+ -+ /* Copy the initial script */ -+ oldmask = umask(077); -+ if((out_fp = fopen(sieve_tmpname, "w")) == NULL) { -+ syslog(LOG_WARNING,"autocreate_sieve: Unable to open %s destination sieve script", sieve_tmpname); -+ unlink(sieve_bctmpname); -+ umask(oldmask); -+ fclose(in_stream); -+ return 1; -+ } -+ umask(oldmask); -+ -+ while((r = fread(buf,sizeof(char), sizeof(buf), in_stream))) { -+ if( fwrite(buf,sizeof(char), r, out_fp) != r) { -+ syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file: %s",sieve_tmpname); -+ fclose(out_fp); -+ unlink(sieve_tmpname); -+ unlink(sieve_bctmpname); -+ fclose(in_stream); -+ return 1; -+ } -+ } -+ -+ if(feof(in_stream)) { -+ fclose(out_fp); -+ } else { /* ferror */ -+ fclose(out_fp); -+ unlink(sieve_tmpname); -+ unlink(sieve_bctmpname); -+ fclose(in_stream); -+ return 1; -+ } -+ -+ /* Renaming the necessary stuff */ -+ if(rename(sieve_tmpname, sieve_script_name)) { -+ unlink(sieve_tmpname); -+ unlink(sieve_bctmpname); -+ return 1; -+ } -+ -+ if(rename(sieve_bctmpname, sieve_bcscript_name)) { -+ unlink(sieve_bctmpname); -+ unlink(sieve_bcscript_name); -+ return 1; -+ } -+ -+ /* end now with the symlink */ -+ if(symlink(sieve_bclink_name, sieve_default)) { -+ if(errno != EEXIST) { -+ syslog(LOG_WARNING, "autocreate_sieve: problem making the default link."); -+ /* Lets delete the files */ -+ unlink(sieve_script_name); -+ unlink(sieve_bcscript_name); -+ } -+ } -+ -+ /* -+ * If everything has succeeded AND we have compiled the script AND we have requested -+ * to generate the global script so that it is not compiled each time then we create it. -+ */ -+ if(do_compile && -+ config_getswitch(IMAPOPT_GENERATE_COMPILED_SIEVE_SCRIPT)) { -+ -+ if(!compiled_source_script) { -+ syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf"); -+ return 0; -+ } -+ -+ if(snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script) >= sizeof(sieve_tmpname)) -+ return 0; -+ -+ /* -+ * Copy everything from the newly created bc sieve sieve script. -+ */ -+ if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) { -+ return 0; -+ } -+ -+ if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { -+ if(errno == EEXIST) { -+ /* Someone is already doing this so just bail out. */ -+ syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname); -+ close(in_fd); -+ return 0; -+ } else if (errno == EACCES) { -+ syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname); -+ close(in_fd); -+ return 0; -+ } else { -+ syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s",sieve_tmpname); -+ close(in_fd); -+ return 0; -+ } -+ } -+ -+ while((r = read(in_fd, buf, sizeof(buf))) > 0) { -+ if((k = write(out_fd,buf,r)) < 0) { -+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno); -+ close(out_fd); -+ close(in_fd); -+ unlink(sieve_tmpname); -+ return 0; -+ } -+ } -+ -+ if(r == 0 ) { /*EOF */ -+ close(out_fd); -+ close(in_fd); -+ } else if (r < 0) { -+ syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s, error: %d", sieve_tmpname, errno); -+ close(out_fd); -+ close(in_fd); -+ unlink(sieve_tmpname); -+ return 0; -+ } -+ -+ /* Rename the temporary created sieve script to its final name. */ -+ if(rename(sieve_tmpname, compiled_source_script)) { -+ if(errno != EEXIST) { -+ unlink(sieve_tmpname); -+ unlink(compiled_source_script); -+ } -+ return 0; -+ } -+ -+ syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script); -+ } -+ -+ return 0; -+} -+ -+static void fatal(const char *s, int code) -+{ -+ printf("Fatal error: %s (%d)\r\n", s, code); -+ exit(1); -+} -+ -+/* to make larry's stupid functions happy :) */ -+static void foo(void) -+{ -+ fatal("stub function called", 0); -+} -+ -+static int sieve_notify(void *ac __attribute__((unused)), -+ void *interp_context __attribute__((unused)), -+ void *script_context __attribute__((unused)), -+ void *message_context __attribute__((unused)), -+ const char **errmsg __attribute__((unused))) -+{ -+ fatal("stub function called", 0); -+ return SIEVE_FAIL; -+} -+ -+static int mysieve_error(int lineno, const char *msg, -+ void *i __attribute__((unused)), void *s) -+{ -+ char buf[1024]; -+ char **errstr = (char **) s; -+ -+ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg); -+ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30); -+ syslog(LOG_DEBUG, "%s", buf); -+ strcat(*errstr, buf); -+ -+ return SIEVE_OK; -+} -+ -+/* end the boilerplate */ -+ -+/* returns TRUE or FALSE */ -+int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret) -+{ -+ sieve_interp_t *i; -+ sieve_script_t *s; -+ int res; -+ -+ res = sieve_interp_alloc(&i, NULL); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_interp_alloc() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_redirect(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_redirect() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_discard(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_discard() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_reject(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_reject() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_fileinto(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_fileinto() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_keep(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_keep() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_imapflags(i, NULL); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_imapflags() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_size(i, (sieve_get_size *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_size() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_header(i, (sieve_get_header *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_header() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_envelope() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_vacation(i, &vacation2); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_vacation() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_notify(i, &sieve_notify); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_notify() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_parse_error(i, &mysieve_error); -+ if (res != SIEVE_OK) { -+ syslog(LOG_WARNING, "sieve_register_parse_error() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ rewind(stream); -+ -+ *errstr = (char *) xmalloc(20 * sizeof(char)); -+ strcpy(*errstr, "script errors:\r\n"); -+ -+ res = sieve_script_parse(i, stream, errstr, &s); -+ -+ if (res == SIEVE_OK) { -+ if(ret) { -+ *ret = s; -+ } else { -+ sieve_script_free(&s); -+ } -+ free(*errstr); -+ *errstr = NULL; -+ } -+ -+ /* free interpreter */ -+ sieve_interp_free(&i); -+ -+ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL; -+} -+ -+/* -+ * Btw the initial date of this patch is Sep, 02 2004 which is the birthday of -+ * Pavlos. Author of cyrusmaster. So consider this patch as his birthday present -+ */ -+ -diff -Naur cyrus-imapd-2.3.9/imap/compile_sieve.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/compile_sieve.c ---- cyrus-imapd-2.3.9/imap/compile_sieve.c 1970-01-01 02:00:00.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/compile_sieve.c 2007-08-21 14:59:22.000000000 +0300 -@@ -0,0 +1,364 @@ -+/* This tool compiles the sieve script from a command -+line so that it can be used wby the autoadd patch */ -+#include -+#include -+ -+#include -+#include -+#ifdef HAVE_UNISTD_H -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "global.h" -+ -+#include "util.h" -+#include "mailbox.h" -+#include "imap_err.h" -+#include "sieve_interface.h" -+#include "script.h" -+ -+#include -+ -+#define TIMSIEVE_FAIL -1 -+#define TIMSIEVE_OK 0 -+#define MAX_FILENAME_SIZE 100 -+ -+/* Needed by libconfig */ -+const int config_need_data = 0; -+ -+static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret); -+ -+static void fatal(const char *s, int code) -+{ -+ printf("Fatal error: %s (%d)\r\n", s, code); -+ -+ exit(1); -+} -+ -+void usage(void) -+{ -+ fprintf(stderr, -+ "Usage:\n\tcompile_sieve [-C ] [-i -o ]\n"); -+ exit(-1); -+} -+ -+ -+int main (int argc, char **argv) -+{ -+ -+ sieve_script_t *s = NULL; -+ bytecode_info_t *bc = NULL; -+ char *err = NULL; -+ FILE *in_stream; -+ int out_fd,r, k, opt; -+ char *source_script = NULL; -+ char *compiled_source_script = NULL; -+ mode_t oldmask; -+ struct stat statbuf; -+ char *alt_config = NULL; -+ extern char *optarg; -+ char sieve_tmpname[MAX_MAILBOX_NAME+1]; -+ -+ if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE); -+ -+ while((opt = getopt(argc, argv, "C:i:o:")) != EOF) { -+ switch (opt) { -+ case 'C': /* alt config file */ -+ alt_config = optarg; -+ break; -+ case 'i': /* input script file */ -+ source_script = optarg; -+ break; -+ case 'o': /* output script file */ -+ compiled_source_script = optarg; -+ break; -+ default: -+ usage(); -+ break; -+ } -+ } -+ -+ if(source_script && !compiled_source_script) { -+ fprintf(stderr, "No output file was defined\n"); -+ usage(); -+ } else if (!source_script && compiled_source_script) { -+ fprintf(stderr, "No input file was defined\n"); -+ usage(); -+ } -+ -+ /* -+ * If no has been defined, then read them from -+ * the configuration file. -+ */ -+ if (!source_script && !compiled_source_script) { -+ cyrus_init(alt_config, "compile_sieve", 0); -+ -+ /* Initially check if we want to have the sieve script created */ -+ if(!(source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT))) { -+ fprintf(stderr,"autocreate_sieve_script option not defined. Check imapd.conf\n"); -+ return 1; -+ } -+ -+ /* Check if we have an already compiled sieve script*/ -+ if(!(compiled_source_script = (char *) config_getstring(IMAPOPT_AUTOCREATE_SIEVE_COMPILEDSCRIPT))) { -+ fprintf(stderr, "autocreate_sieve_compiledscript option not defined. Check imapd.conf\n"); -+ return 1; -+ } -+ -+ if(!strrchr(source_script,'/') || !strrchr(compiled_source_script,'/')) { -+ /* -+ * At this point the only think that is inconsistent is the directory -+ * that was created. But if the user will have any sieve scripts then -+ * they will eventually go there, so no big deal -+ */ -+ fprintf(stderr, -+ "In imapd.conf the full path of the filenames must be defined\n"); -+ return 1; -+ } -+ } -+ -+ printf("input file : %s, output file : %s\n", source_script, compiled_source_script); -+ -+ -+ if(strlen(compiled_source_script) + sizeof(".NEW") + 1 > sizeof(sieve_tmpname)) { -+ fprintf(stderr, "Filename %s is too big\n", compiled_source_script); -+ return 1; -+ } -+ -+ snprintf(sieve_tmpname, sizeof(sieve_tmpname), "%s.NEW", compiled_source_script); -+ -+ in_stream = fopen(source_script,"r"); -+ -+ if(!in_stream) { -+ fprintf(stderr,"Unable to open %s source sieve script\n",source_script); -+ return; -+ } -+ -+ /* -+ * We open the file that will be used as the bc file. If this file exists, overwrite it -+ * since something bad has happened. We open the file here so that this error checking is -+ * done before we try to open the rest of the files to start copying etc. -+ */ -+ out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); -+ if(out_fd < 0) { -+ if(errno == EEXIST) { -+ fprintf(stderr, "File %s already exists\n", sieve_tmpname); -+ } else if (errno == EACCES) { -+ fprintf(stderr,"No access to create file %s. Please check that you have the correct permissions\n", -+ sieve_tmpname); -+ } else { -+ fprintf(stderr,"Unable to create %s. Please check that you have the correct permissions\n", -+ sieve_tmpname); -+ } -+ -+ fclose(in_stream); -+ return 1; -+ } -+ -+ if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) { -+ if(err && *err) { -+ fprintf(stderr, "Error while parsing script %s\n",err); -+ free(err); -+ } -+ else -+ fprintf(stderr,"Error while parsing script\n"); -+ unlink(sieve_tmpname); -+ fclose(in_stream); -+ close(out_fd); -+ return; -+ } -+ -+ -+ /* generate the bytecode */ -+ if(sieve_generate_bytecode(&bc,s) == TIMSIEVE_FAIL) { -+ fprintf(stderr,"Error occured while compiling sieve script\n"); -+ /* removing the copied script and cleaning up memory */ -+ unlink(sieve_tmpname); -+ sieve_script_free(&s); -+ fclose(in_stream); -+ close(out_fd); -+ return; -+ } -+ if(sieve_emit_bytecode(out_fd,bc) == TIMSIEVE_FAIL) { -+ fprintf(stderr, "Error occured while emitting sieve script\n"); -+ unlink(sieve_tmpname); -+ sieve_free_bytecode(&bc); -+ sieve_script_free(&s); -+ fclose(in_stream); -+ close(out_fd); -+ return; -+ } -+ -+ /* clean up the memory */ -+ sieve_free_bytecode(&bc); -+ sieve_script_free(&s); -+ -+ close(out_fd); -+ -+ if(rename(sieve_tmpname, compiled_source_script)) { -+ if(errno != EEXIST) { -+ unlink(sieve_tmpname); -+ unlink(compiled_source_script); -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+ -+/* to make larry's stupid functions happy :) */ -+static void foo(void) -+{ -+ fatal("stub function called", 0); -+} -+ -+extern sieve_vacation_t vacation2;/* = { -+ 0, / min response / -+ 0, / max response / -+ (sieve_callback *) &foo, / autorespond() / -+ (sieve_callback *) &foo / send_response() / -+}; */ -+ -+static int sieve_notify(void *ac __attribute__((unused)), -+ void *interp_context __attribute__((unused)), -+ void *script_context __attribute__((unused)), -+ void *message_context __attribute__((unused)), -+ const char **errmsg __attribute__((unused))) -+{ -+ fatal("stub function called", 0); -+ return SIEVE_FAIL; -+} -+ -+static int mysieve_error(int lineno, const char *msg, -+ void *i __attribute__((unused)), void *s) -+{ -+ char buf[1024]; -+ char **errstr = (char **) s; -+ -+ snprintf(buf, 80, "line %d: %s\r\n", lineno, msg); -+ *errstr = (char *) xrealloc(*errstr, strlen(*errstr) + strlen(buf) + 30); -+ fprintf(stderr, "%s\n", buf); -+ strcat(*errstr, buf); -+ -+ return SIEVE_OK; -+} -+ -+/* end the boilerplate */ -+ -+/* returns TRUE or FALSE */ -+int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret) -+{ -+ sieve_interp_t *i; -+ sieve_script_t *s; -+ int res; -+ -+ res = sieve_interp_alloc(&i, NULL); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_interp_alloc() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_redirect(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_redirect() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_discard(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_discard() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_reject(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_reject() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_fileinto(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_fileinto() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ res = sieve_register_keep(i, (sieve_callback *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_keep() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_imapflags(i, NULL); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_imapflags() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_size(i, (sieve_get_size *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_size() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_header(i, (sieve_get_header *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_header() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_envelope(i, (sieve_get_envelope *) &foo); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_envelope() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_vacation(i, &vacation2); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_vacation() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_notify(i, &sieve_notify); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_notify() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ res = sieve_register_parse_error(i, &mysieve_error); -+ if (res != SIEVE_OK) { -+ fprintf(stderr, "sieve_register_parse_error() returns %d\n", res); -+ return TIMSIEVE_FAIL; -+ } -+ -+ rewind(stream); -+ -+ *errstr = (char *) xmalloc(20 * sizeof(char)); -+ strcpy(*errstr, "script errors:\r\n"); -+ -+ res = sieve_script_parse(i, stream, errstr, &s); -+ -+ if (res == SIEVE_OK) { -+ if(ret) { -+ *ret = s; -+ } else { -+ sieve_script_free(&s); -+ } -+ free(*errstr); -+ *errstr = NULL; -+ } -+ -+ /* free interpreter */ -+ sieve_interp_free(&i); -+ -+ return (res == SIEVE_OK) ? TIMSIEVE_OK : TIMSIEVE_FAIL; -+} -+ -+ -+ -+ -+ -+ -diff -Naur cyrus-imapd-2.3.9/imap/imapd.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/imapd.c ---- cyrus-imapd-2.3.9/imap/imapd.c 2007-08-02 17:18:51.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/imapd.c 2007-08-21 14:59:22.000000000 +0300 -@@ -204,6 +204,7 @@ - void motd_file(int fd); - void shut_down(int code); - void fatal(const char *s, int code); -+void autocreate_inbox(void); - - void cmdloop(void); - void cmd_login(char *tag, char *user); -@@ -1909,6 +1910,43 @@ - } - - /* -+ * Autocreate Inbox and subfolders upon login -+ */ -+void autocreate_inbox() -+{ -+ char inboxname[MAX_MAILBOX_NAME+1]; -+ int autocreatequota; -+ int r; -+ -+ /* -+ * Exlude admin's accounts -+ */ -+ if (imapd_userisadmin || imapd_userisproxyadmin) -+ return; -+ -+ /* -+ * Exclude anonymous -+ */ -+ if (!strcmp(imapd_userid, "anonymous")) -+ return; -+ -+ if ((autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { -+ /* This is actyally not required -+ as long as the lenght of userid is ok */ -+ r = (*imapd_namespace.mboxname_tointernal) (&imapd_namespace, -+ "INBOX", imapd_userid, inboxname); -+ if (!r) -+ r = mboxlist_lookup(inboxname, NULL, NULL); -+ -+ if (r == IMAP_MAILBOX_NONEXISTENT) { -+ mboxlist_autocreateinbox(&imapd_namespace, imapd_userid, -+ imapd_authstate, inboxname, autocreatequota); -+ } -+ } -+} -+ -+ -+/* - * Perform a LOGIN command - */ - void cmd_login(char *tag, char *user) -@@ -2076,6 +2114,9 @@ - strcspn(imapd_userid, "@") : 0); - - freebuf(&passwdbuf); -+ -+ autocreate_inbox(); -+ - return; - } - -@@ -2232,6 +2273,8 @@ - config_virtdomains ? - strcspn(imapd_userid, "@") : 0); - -+ autocreate_inbox(); -+ - return; - } - -diff -Naur cyrus-imapd-2.3.9/imap/lmtpd.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/lmtpd.c ---- cyrus-imapd-2.3.9/imap/lmtpd.c 2007-07-18 21:11:55.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/lmtpd.c 2007-08-21 14:59:22.000000000 +0300 -@@ -117,6 +117,8 @@ - static FILE *spoolfile(message_data_t *msgdata); - static void removespool(message_data_t *msgdata); - -+static int autocreate_inbox(const char *user, const char *domain); -+ - /* current namespace */ - static struct namespace lmtpd_namespace; - -@@ -950,6 +952,86 @@ - exit(code); - } - -+ -+/* -+ * Autocreate Inbox and subfolders upon login -+ */ -+int autocreate_inbox(const char *user, const char *domain) -+{ -+ struct auth_state *auth_state; -+ char inboxname[MAX_MAILBOX_NAME+1]; -+ char *rcpt_userid = NULL; -+ int autocreatequota; -+ int r = 0; -+ -+ if (user == NULL) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ if (domain != NULL) { -+ int k; -+ -+ rcpt_userid = (char *) xmalloc((strlen(user) + strlen(domain) + 2) * sizeof(char)); -+ k = strlcpy(rcpt_userid, user, strlen(user) + 1); -+ *(rcpt_userid + k) = '@'; -+ strlcpy(rcpt_userid + k + 1, domain, strlen(domain) + 1); -+ } else { -+ rcpt_userid = (char *) user; -+ } -+ -+ -+ /* -+ * Exclude anonymous -+ */ -+ if (!strcmp(rcpt_userid, "anonymous")) { -+ if (rcpt_userid != user) { -+ free(rcpt_userid); -+ } -+ -+ return IMAP_MAILBOX_NONEXISTENT; -+ } -+ -+ /* -+ * Check for autocreatequota and createonpost -+ */ -+ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA)) || -+ !(config_getswitch(IMAPOPT_CREATEONPOST))) { -+ -+ if (rcpt_userid != user) { -+ free(rcpt_userid); -+ } -+ -+ return IMAP_MAILBOX_NONEXISTENT; -+ } -+ -+ -+ /* -+ * Exclude admin's accounts -+ */ -+ auth_state = auth_newstate(rcpt_userid); -+ -+ if (global_authisa(auth_state, IMAPOPT_ADMINS)) { -+ if (rcpt_userid != user) { -+ free(rcpt_userid); -+ } -+ -+ return IMAP_MAILBOX_NONEXISTENT; -+ } -+ -+ r = (*lmtpd_namespace.mboxname_tointernal) (&lmtpd_namespace, -+ "INBOX", rcpt_userid, inboxname); -+ -+ if (!r) -+ r = mboxlist_autocreateinbox(&lmtpd_namespace, rcpt_userid, -+ auth_state, inboxname, autocreatequota); -+ -+ if (rcpt_userid != user) { -+ free(rcpt_userid); -+ } -+ -+ return r; -+} -+ -+ - static int verify_user(const char *user, const char *domain, char *mailbox, - long quotacheck, struct auth_state *authstate) - { -@@ -993,6 +1075,15 @@ - */ - r = mlookup(namebuf, &server, &acl, NULL); - -+ /* If user mailbox does not exist, then invoke autocreate inbox function */ -+ if (r == IMAP_MAILBOX_NONEXISTENT) { -+ r = autocreate_inbox(user, domain); -+ -+ /* Try to locate the mailbox again */ -+ if (!r) -+ r = mlookup(namebuf, &server, &acl, NULL); -+ } -+ - if (r == IMAP_MAILBOX_NONEXISTENT && !user && - config_getswitch(IMAPOPT_LMTP_FUZZY_MAILBOX_MATCH) && - /* see if we have a mailbox whose name is close */ -@@ -1019,6 +1110,7 @@ - aclcheck, (quotacheck < 0) - || config_getswitch(IMAPOPT_LMTP_STRICT_QUOTA) ? - quotacheck : 0); -+ - } - } - -diff -Naur cyrus-imapd-2.3.9/imap/mboxlist.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/mboxlist.c ---- cyrus-imapd-2.3.9/imap/mboxlist.c 2007-08-15 20:20:55.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/mboxlist.c 2007-08-21 14:59:22.000000000 +0300 -@@ -83,6 +83,12 @@ - #include "mboxlist.h" - #include "quota.h" - -+#ifdef USE_SIEVE -+extern int autoadd_sieve(char *userid, -+ const char *source_script); -+#endif -+ -+ - #define DB config_mboxlist_db - #define SUBDB config_subscription_db - -@@ -100,11 +106,29 @@ - static int mboxlist_changequota(const char *name, int matchlen, int maycreate, - void *rock); - -+static int mboxlist_autochangesub(char *name, int matchlen, int maycreate, -+ void *rock); -+ -+static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace, -+ char *userid, char *auth_userid, -+ struct auth_state *auth_state); -+ - struct change_rock { - struct quota *quota; - struct txn **tid; - }; - -+/* -+ * Struct needed to be passed as void *rock to -+ * mboxlist_autochangesub(); -+ */ -+struct changesub_rock_st { -+ char *userid; -+ char *auth_userid; -+ struct auth_state *auth_state; -+}; -+ -+ - #define FNAME_SUBSSUFFIX ".sub" - - /* -@@ -3261,3 +3285,349 @@ - - return DB->abort(mbdb, tid); - } -+ -+/* -+ * Automatically subscribe user to *ALL* shared folders, -+ * one has permissions to be subscribed to. -+ * INBOX subfolders are excluded. -+ */ -+static int mboxlist_autochangesub(char *name, int matchlen, int maycreate, -+ void *rock) { -+ -+ struct changesub_rock_st *changesub_rock = (struct changesub_rock_st *) rock; -+ char *userid = changesub_rock->userid; -+ char *auth_userid = changesub_rock->auth_userid; -+ struct auth_state *auth_state = changesub_rock->auth_state; -+ int r; -+ -+ -+ if((strlen(name) == 5 && !strncmp(name, "INBOX", 5)) || /* Exclude INBOX */ -+ (strlen(name) > 5 && !strncmp(name, "INBOX.",6)) || /* Exclude INBOX subfolders */ -+ (strlen(name) > 4 && !strncmp(name, "user.", 5))) /* Exclude other users' folders */ -+ return 0; -+ -+ -+ r = mboxlist_changesub(name, userid, auth_state, 1, 0); -+ -+ if (r) { -+ syslog(LOG_WARNING, -+ "autosubscribe: User %s to folder %s, subscription failed: %s", -+ auth_userid, name, error_message(r)); -+ } else { -+ syslog(LOG_NOTICE, -+ "autosubscribe: User %s to folder %s, subscription succeeded", -+ auth_userid, name); -+ } -+ -+ return 0; -+} -+ -+#define SEP '|' -+ -+/* -+ * Automatically subscribe user to a shared folder. -+ * Subscription is done successfully, if the shared -+ * folder exists and the user has the necessary -+ * permissions. -+ */ -+static int mboxlist_autosubscribe_sharedfolders(struct namespace *namespace, -+ char *userid, char *auth_userid, -+ struct auth_state *auth_state) { -+ -+ const char *sub ; -+ char *p, *q, *next_sub; -+ char folder[MAX_MAILBOX_NAME+1], name[MAX_MAILBOX_NAME+1], mailboxname[MAX_MAILBOX_NAME+1]; -+ int len; -+ int r = 0; -+ int subscribe_all_sharedfolders = 0; -+ -+ subscribe_all_sharedfolders = config_getswitch(IMAPOPT_AUTOSUBSCRIBE_ALL_SHAREDFOLDERS); -+ -+ /* -+ * If subscribeallsharedfolders is set to yes in imapd.conf, then -+ * subscribe user to every shared folder one has the apropriate -+ * permissions. -+ */ -+ if(subscribe_all_sharedfolders) { -+ char pattern[MAX_MAILBOX_PATH+1]; -+ struct changesub_rock_st changesub_rock; -+ -+ strcpy(pattern, "*"); -+ changesub_rock.userid = userid; -+ changesub_rock.auth_userid = auth_userid; -+ changesub_rock.auth_state = auth_state; -+ -+ r = mboxlist_findall(namespace, pattern, 0, userid, -+ auth_state, mboxlist_autochangesub, &changesub_rock); -+ -+ return r; -+ } -+ -+ if ((sub=config_getstring(IMAPOPT_AUTOSUBSCRIBESHAREDFOLDERS)) == NULL) -+ return r; -+ -+ next_sub = (char *) sub; -+ while (*next_sub) { -+ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++); -+ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++); -+ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--); -+ if (!*p ) continue; -+ -+ len = q - p + 1; -+ /* Check for folder length */ -+ if (len > sizeof(folder)-1) -+ continue; -+ -+ if (!r) { -+ strncpy(folder, p, len); -+ folder[len] = '\0'; -+ -+ strlcpy(name, namespace->prefix[NAMESPACE_SHARED], sizeof(name)); -+ len = strlcat(name, folder, sizeof(name)); -+ -+ r = (namespace->mboxname_tointernal) (namespace, name, userid, -+ mailboxname); -+ } -+ -+ if (!r) -+ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 0); -+ -+ if (!r) { -+ syslog(LOG_NOTICE, "autosubscribe: User %s to %s succeeded", -+ userid, folder); -+ } else { -+ syslog(LOG_WARNING, "autosubscribe: User %s to %s failed: %s", -+ userid, folder, error_message(r)); -+ r = 0; -+ } -+ } -+ -+ return r; -+} -+ -+ -+ -+int mboxlist_autocreateinbox(struct namespace *namespace, -+ char *userid, -+ struct auth_state *auth_state, -+ char *mailboxname, int autocreatequota) { -+ char name [MAX_MAILBOX_NAME+1]; -+ char folder [MAX_MAILBOX_NAME+1]; -+ char *auth_userid = NULL; -+ char *partition = NULL; -+ const char *crt; -+ const char *sub; -+ char *p, *q, *next_crt, *next_sub; -+ int len; -+ int r = 0; -+ int numcrt = 0; -+ int numsub = 0; -+#ifdef USE_SIEVE -+ const char *source_script; -+#endif -+ -+ -+ -+ auth_userid = auth_canonuser(auth_state); -+ if (auth_userid == NULL) { -+ /* -+ * Couldn't get cannon userid -+ */ -+ syslog(LOG_ERR, -+ "autocreateinbox: Could not get canonified userid for user %s", userid); -+ return IMAP_PARTITION_UNKNOWN; -+ } -+ -+ /* Added this for debug information. */ -+ syslog(LOG_DEBUG, "autocreateinbox: autocreate inbox for user %s was called", auth_userid); -+ -+ /* -+ * While this is not needed for admins -+ * and imap_admins accounts, it would be -+ * better to separate *all* admins and -+ * proxyservers from normal accounts -+ * (accounts that have mailboxes). -+ * UOA Specific note(1): Even if we do not -+ * exclude these servers-classes here, -+ * UOA specific code, will neither return -+ * role, nor create INBOX, because none of these -+ * administrative accounts belong to the -+ * mailRecipient objectclass, or have imapPartition. -+ * UOA Specific note(2): Another good reason for doing -+ * this, is to prevent the code, from getting into -+ * cyrus_ldap.c because of the continues MSA logins to LMTPd. -+ */ -+ -+ /* -+ * admins and the coresponding imap -+ * service, had already been excluded. -+ */ -+ -+ /* -+ * Do we really need group membership -+ * for admins or service_admins? -+ */ -+ if (global_authisa(auth_state, IMAPOPT_ADMINS)) return 0; -+ -+ /* -+ * Do we really need group membership -+ * for proxyservers? -+ */ -+ if (global_authisa(auth_state, IMAPOPT_PROXYSERVERS)) return 0; -+ -+ /* -+ * Check if user belongs to the autocreate_users group. This option -+ * controls for whom the mailbox may be automatically created. Default -+ * value for this option is 'anyone'. So, if not declared, all mailboxes -+ * will be created. -+ */ -+ if (!global_authisa(auth_state, IMAPOPT_AUTOCREATE_USERS)) { -+ syslog(LOG_DEBUG, "autocreateinbox: User %s does not belong to the autocreate_users. No mailbox is created", -+ auth_userid); -+ return IMAP_MAILBOX_NONEXISTENT; -+ } -+ -+#if 0 -+ /* -+ * Get Partition info or return. -+ * (Here you should propably use -+ * you own "get_partition(char *userid)" -+ * function. Otherwise all new INBOXes will be -+ * created into whatever partition has been declared -+ * as default in your imapd.conf) -+ */ -+ -+ partition = get_partition(userid); -+ if (partition == NULL) { -+ /* -+ * Couldn't get partition info -+ */ -+ syslog(LOG_ERR, -+ "Could not get imapPartition info for user %s", userid); -+ return IMAP_PARTITION_UNKNOWN; -+ } -+#endif -+ -+ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, -+ 1, userid, auth_state, 0, 0, 0); -+ -+ if (!r && autocreatequota > 0) -+ r = mboxlist_setquota(mailboxname, autocreatequota, 0); -+ -+ if (!r) -+ r = mboxlist_changesub(mailboxname, userid, -+ auth_state, 1, 1); -+ -+ if (!r) { -+ syslog(LOG_NOTICE, "autocreateinbox: User %s, INBOX was successfully created in partition %s", -+ auth_userid, partition == NULL ? "default" : partition); -+ } else { -+ syslog(LOG_ERR, "autocreateinbox: User %s, INBOX failed. %s", -+ auth_userid, error_message(r)); -+ } -+ -+#if 0 -+ /* Allocated from get_partition, and not needed any more */ -+ free_partition(partition); -+#endif -+ -+ if (r) return r; -+ -+ /* INBOX's subfolders */ -+ if ((crt=config_getstring(IMAPOPT_AUTOCREATEINBOXFOLDERS))) -+ sub=config_getstring(IMAPOPT_AUTOSUBSCRIBEINBOXFOLDERS); -+ -+ /* Roll through crt */ -+ next_crt = (char *) crt; -+ while (next_crt!=NULL && *next_crt) { -+ for (p = next_crt ; isspace((int) *p) || *p == SEP ; p++); -+ for (next_crt = p ; *next_crt && *next_crt != SEP ; next_crt++); -+ for (q = next_crt ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--); -+ -+ if (!*p) continue; -+ -+ len = q - p + 1; -+ -+ /* First time we check for length */ -+ if (len > sizeof(folder) - 5) -+ r = IMAP_MAILBOX_BADNAME; -+ -+ if (!r) { -+ strncpy(folder, p, len); -+ folder[len] = '\0'; -+ -+ strlcpy(name, namespace->prefix[NAMESPACE_INBOX], sizeof(name)); -+ len = strlcat(name, folder, sizeof(name)); -+ } -+ -+ if (!r) -+ r = (namespace->mboxname_tointernal) (namespace, name, userid, -+ mailboxname); -+ if (!r) -+ r = mboxlist_createmailbox(mailboxname, MAILBOX_FORMAT_NORMAL, NULL, -+ 1, userid, auth_state, 0, 0, 0); -+ -+ if (!r) { -+ numcrt++; -+ syslog(LOG_NOTICE, "autocreateinbox: User %s, subfolder %s creation succeeded.", -+ auth_userid, name); -+ } else { -+ syslog(LOG_WARNING, "autocreateinbox: User %s, subfolder %s creation failed. %s", -+ auth_userid, name, error_message(r)); -+ r=0; -+ continue; -+ } -+ -+ /* Roll through sub */ -+ next_sub = (char *) sub; -+ while (next_sub!=NULL && *next_sub) { -+ for (p = next_sub ; isspace((int) *p) || *p == SEP ; p++); -+ for (next_sub = p ; *next_sub && *next_sub != SEP ; next_sub++); -+ for (q = next_sub ; q > p && (isspace((int) *q) || *q == SEP || !*q) ; q--); -+ if (!*p ) continue; -+ -+ len = q - p + 1; -+ -+ if (len != strlen(folder) || strncmp(folder, p, len)) -+ continue; -+ -+ r = mboxlist_changesub(mailboxname, userid, auth_state, 1, 1); -+ -+ if (!r) { -+ numsub++; -+ syslog(LOG_NOTICE,"autocreateinbox: User %s, subscription to %s succeeded", -+ auth_userid, name); -+ } else -+ syslog(LOG_WARNING, "autocreateinbox: User %s, subscription to %s failed. %s", -+ auth_userid, name, error_message(r)); -+ -+ break; -+ } -+ } -+ -+ if (crt!=NULL && *crt) -+ syslog(LOG_INFO, "User %s, Inbox subfolders, created %d, subscribed %d", -+ auth_userid, numcrt, numsub); -+ -+ /* -+ * Check if shared folders are available for subscription. -+ */ -+ mboxlist_autosubscribe_sharedfolders(namespace, userid, auth_userid, auth_state); -+ -+#ifdef USE_SIEVE -+ /* -+ * Here the autocreate sieve script feature is iniated from. -+ */ -+ source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT); -+ -+ if (source_script) { -+ if (!autoadd_sieve(userid, source_script)) -+ syslog(LOG_NOTICE, "autocreate_sieve: User %s, default sieve script creation succeeded", auth_userid); -+ else -+ syslog(LOG_WARNING, "autocreate_sieve: User %s, default sieve script creation failed", auth_userid); -+ } -+#endif -+ -+ return r; -+} -+ -diff -Naur cyrus-imapd-2.3.9/imap/mboxlist.h cyrus-imapd-2.3.9-autocreate.uncompiled/imap/mboxlist.h ---- cyrus-imapd-2.3.9/imap/mboxlist.h 2006-11-30 19:11:19.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/mboxlist.h 2007-08-21 14:59:22.000000000 +0300 -@@ -204,4 +204,10 @@ - int mboxlist_commit(struct txn *tid); - int mboxlist_abort(struct txn *tid); - -+int mboxlist_autocreateinbox(struct namespace *namespace, -+ char *userid, -+ struct auth_state *auth_state, -+ char *mailboxname, int autocreatequota); -+ -+ - #endif -diff -Naur cyrus-imapd-2.3.9/imap/pop3d.c cyrus-imapd-2.3.9-autocreate.uncompiled/imap/pop3d.c ---- cyrus-imapd-2.3.9/imap/pop3d.c 2007-03-30 21:51:01.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/imap/pop3d.c 2007-08-21 14:59:22.000000000 +0300 -@@ -158,6 +158,8 @@ - static char popd_apop_chal[45 + MAXHOSTNAMELEN + 1]; /* */ - static void cmd_apop(char *response); - -+static int autocreate_inbox(char *inboxname, char *userid); -+ - static void cmd_auth(char *arg); - static void cmd_capa(void); - static void cmd_pass(char *pass); -@@ -1226,6 +1228,7 @@ - popd_userid = xstrdup(userbuf); - prot_printf(popd_out, "+OK Name is a valid mailbox\r\n"); - } -+ - } - - void cmd_pass(char *pass) -@@ -1500,6 +1503,43 @@ - } - - /* -+ * Autocreate Inbox and subfolders upon login -+ */ -+int autocreate_inbox(char *inboxname, char *auth_userid) -+{ -+ struct auth_state *auth_state; -+ int autocreatequota; -+ int r; -+ -+ if (inboxname == NULL || auth_userid == NULL) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ /* -+ * Exclude anonymous -+ */ -+ if (!strcmp(popd_userid, "anonymous")) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ /* -+ * Check for autocreatequota -+ */ -+ if (!(autocreatequota = config_getint(IMAPOPT_AUTOCREATEQUOTA))) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ /* -+ * Exclude admin's accounts -+ */ -+ auth_state = auth_newstate(popd_userid); -+ if (global_authisa(auth_state, IMAPOPT_ADMINS)) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ r = mboxlist_autocreateinbox(&popd_namespace, auth_userid, -+ auth_state, inboxname, autocreatequota); -+ return r; -+} -+ -+ -+/* - * Complete the login process by opening and locking the user's inbox - */ - int openinbox(void) -@@ -1528,6 +1568,12 @@ - - if (!r) r = mboxlist_detail(inboxname, &type, NULL, NULL, - &server, &acl, NULL); -+ -+ /* Try once again after autocreate_inbox */ -+ if (r == IMAP_MAILBOX_NONEXISTENT && !(r = autocreate_inbox(inboxname, userid))) -+ r = mboxlist_detail(inboxname, &type, NULL, NULL, -+ &server, &acl, NULL); -+ - if (!r && (config_popuseacl = config_getswitch(IMAPOPT_POPUSEACL)) && - (!acl || - !((myrights = cyrus_acl_myrights(popd_authstate, acl)) & ACL_READ))) { -diff -Naur cyrus-imapd-2.3.9/lib/auth.c cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth.c ---- cyrus-imapd-2.3.9/lib/auth.c 2006-11-30 19:11:22.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth.c 2007-08-21 14:59:22.000000000 +0300 -@@ -117,3 +117,11 @@ - - auth->freestate(auth_state); - } -+ -+char *auth_canonuser(struct auth_state *auth_state) -+{ -+ struct auth_mech *auth = auth_fromname(); -+ -+ return auth->auth_canonuser(auth_state); -+} -+ -diff -Naur cyrus-imapd-2.3.9/lib/auth.h cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth.h ---- cyrus-imapd-2.3.9/lib/auth.h 2006-11-30 19:11:22.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth.h 2007-08-21 14:59:22.000000000 +0300 -@@ -54,6 +54,7 @@ - const char *identifier); - struct auth_state *(*newstate)(const char *identifier); - void (*freestate)(struct auth_state *auth_state); -+ char *(*auth_canonuser)(struct auth_state *auth_state); - }; - - extern struct auth_mech *auth_mechs[]; -@@ -76,5 +77,6 @@ - const char *identifier); - struct auth_state *auth_newstate(const char *identifier); - void auth_freestate(struct auth_state *auth_state); -+char *auth_canonuser(struct auth_state *auth_state); - - #endif /* INCLUDED_AUTH_H */ -diff -Naur cyrus-imapd-2.3.9/lib/auth_krb.c cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_krb.c ---- cyrus-imapd-2.3.9/lib/auth_krb.c 2006-11-30 19:11:22.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_krb.c 2007-08-21 14:59:22.000000000 +0300 -@@ -338,6 +338,15 @@ - free((char *)auth_state); - } - -+static char *mycanonuser(struct auth_state *auth_state) -+{ -+ if (auth_state) -+ return auth_state->userid; -+ -+ return NULL; -+} -+ -+ - #else /* HAVE_KRB */ - - static int mymemberof( -@@ -366,6 +375,13 @@ - fatal("Authentication mechanism (krb) not compiled in", EC_CONFIG); - } - -+static char *mycanonuser( -+ struct auth_state *auth_state __attribute__((unused))) -+{ -+ fatal("Authentication mechanism (krb) not compiled in", EC_CONFIG); -+} -+ -+ - #endif - - struct auth_mech auth_krb = -@@ -376,4 +392,5 @@ - &mymemberof, - &mynewstate, - &myfreestate, -+ &mycanonuser, - }; -diff -Naur cyrus-imapd-2.3.9/lib/auth_krb5.c cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_krb5.c ---- cyrus-imapd-2.3.9/lib/auth_krb5.c 2006-11-30 19:11:22.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_krb5.c 2007-08-21 14:59:22.000000000 +0300 -@@ -197,6 +197,14 @@ - free(auth_state); - } - -+static char *mycanonuser(struct auth_state *auth_state) -+{ -+ if (auth_state) -+ return auth_state->userid; -+ -+ return NULL; -+} -+ - #else /* HAVE_GSSAPI_H */ - - static int mymemberof( -@@ -225,6 +233,12 @@ - fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG); - } - -+static char *mycanonuser( -+ struct auth_state *auth_state __attribute__((unused))) -+{ -+ fatal("Authentication mechanism (krb5) not compiled in", EC_CONFIG); -+} -+ - #endif - - struct auth_mech auth_krb5 = -@@ -235,4 +249,5 @@ - &mymemberof, - &mynewstate, - &myfreestate, -+ &mycanonuser, - }; -diff -Naur cyrus-imapd-2.3.9/lib/auth_pts.c cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_pts.c ---- cyrus-imapd-2.3.9/lib/auth_pts.c 2007-08-15 20:20:57.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_pts.c 2007-08-21 14:59:22.000000000 +0300 -@@ -511,6 +511,14 @@ - free(auth_state); - } - -+static char *mycanonuser(struct auth_state *auth_state) -+{ -+ if (auth_state) -+ return auth_state->userid.id; -+ -+ return NULL; -+} -+ - struct auth_mech auth_pts = - { - "pts", /* name */ -@@ -519,4 +527,5 @@ - &mymemberof, - &mynewstate, - &myfreestate, -+ &mycanonuser, - }; -diff -Naur cyrus-imapd-2.3.9/lib/auth_unix.c cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_unix.c ---- cyrus-imapd-2.3.9/lib/auth_unix.c 2007-02-13 18:42:49.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/auth_unix.c 2007-08-21 14:59:22.000000000 +0300 -@@ -269,6 +269,16 @@ - free((char *)auth_state); - } - -+static char *mycanonuser(auth_state) -+ struct auth_state *auth_state; -+{ -+ if (auth_state) -+ return auth_state->userid; -+ -+ return NULL; -+} -+ -+ - - struct auth_mech auth_unix = - { -@@ -278,4 +288,5 @@ - &mymemberof, - &mynewstate, - &myfreestate, -+ &mycanonuser, - }; -diff -Naur cyrus-imapd-2.3.9/lib/imapoptions cyrus-imapd-2.3.9-autocreate.uncompiled/lib/imapoptions ---- cyrus-imapd-2.3.9/lib/imapoptions 2007-03-30 21:51:02.000000000 +0300 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/lib/imapoptions 2007-08-21 14:59:22.000000000 +0300 -@@ -177,6 +177,55 @@ - /* Number of seconds to wait before returning a timeout failure when - performing a client connection (e.g. in a murder environment) */ - -+{ "createonpost", 0, SWITCH } -+/* If yes, when lmtpd receives an incoming mail for an INBOX that does not exist, -+ then the INBOX is automatically created by lmtpd. */ -+ -+{ "autocreateinboxfolders", NULL, STRING } -+/* If a user does not have an INBOX created then the INBOX as well as some INBOX -+ subfolders are created under two conditions. -+ 1. The user logins via the IMAP or the POP3 protocol. (autocreatequota option must have a nonzero value) -+ 2. A message arrives for the user through the LMTPD protocol.(createonpost option must be yes) -+ autocreateinboxfolders is a list of INBOX's subfolders separated by a "|", that -+ are automatically created by the server under the previous two situations. */ -+ -+{ "autosubscribeinboxfolders", NULL, STRING } -+/* A list of folder names, separated by "|", that the users get automatically subscribed to, -+ when their INBOX is created. These folder names must have been included in the -+ autocreateinboxfolders option of the imapd.conf. */ -+ -+{ "autosubscribesharedfolders", NULL, STRING } -+/* A list of shared folders (bulletin boards), separated by "|", that the users get -+ automatically subscribed to, after their INBOX is created. The shared folder must -+ have been created and the user must have the required permissions to get subscribed -+ to it. Otherwise, subscribing to the shared folder fails. */ -+ -+{ "autosubscribe_all_sharedfolders", 0, SWITCH } -+/* If set to yes, the user is automatically subscribed to all shared folders, one has permission -+ to subscribe to. */ -+ -+{ "autocreate_sieve_script", NULL, STRING } -+/* The full path of a file that contains a sieve script. This script automatically becomes a -+ user's initial default sieve filter script. When this option is not defined, no default -+ sieve filter is created. The file must be readable by the cyrus daemon. */ -+ -+{ "autocreate_sieve_compiledscript", NULL, STRING } -+/* The full path of a file that contains a compiled in bytecode sieve script. This script -+ automatically becomes a user's initial default sieve filter script. If this option is -+ not specified, or the filename doesn't exist then the script defined by -+ autocreate_sieve_script is compiled on the fly and installed as the user's default -+ sieve script */ -+ -+{ "generate_compiled_sieve_script", 0, SWITCH } -+/* If set to yes and no compiled sieve script file exists, the sieve script which is -+ compiled on the fly will be saved in the file name that autocreate_sieve_compiledscript -+ option points to. In order a compiled script to be generated, autocreate_sieve_script and -+ autocreate_sieve_compiledscript must have valid values */ -+ -+{ "autocreate_users", "anyone", STRING } -+/* A space separated list of users and/or groups that are allowed their INBOX to be -+ automatically created. */ -+ - { "configdirectory", NULL, STRING } - /* The pathname of the IMAP configuration directory. This field is - required. */ -diff -Naur cyrus-imapd-2.3.9/notifyd/Makefile.in cyrus-imapd-2.3.9-autocreate.uncompiled/notifyd/Makefile.in ---- cyrus-imapd-2.3.9/notifyd/Makefile.in 2006-11-30 19:11:23.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/notifyd/Makefile.in 2007-08-21 14:59:22.000000000 +0300 -@@ -69,10 +69,11 @@ - SERVICE=../master/service.o - - IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@ -+SIEVE_LIBS = @SIEVE_LIBS@ - IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@ - LIB_WRAP = @LIB_WRAP@ - LIBS = @ZEPHYR_LIBS@ @LIBS@ $(IMAP_COM_ERR_LIBS) --DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ -+DEPLIBS=../imap/mutex_fake.o ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ - - PURIFY=/usr/local/bin/purify - PUREOPT=-best-effort -diff -Naur cyrus-imapd-2.3.9/notifyd/notifyd.c cyrus-imapd-2.3.9-autocreate.uncompiled/notifyd/notifyd.c ---- cyrus-imapd-2.3.9/notifyd/notifyd.c 2006-11-30 19:11:23.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/notifyd/notifyd.c 2007-08-21 14:59:22.000000000 +0300 -@@ -97,7 +97,7 @@ - - #define NOTIFY_MAXSIZE 8192 - --int do_notify() -+static int do_notify() - { - struct sockaddr_un sun_data; - socklen_t sunlen = sizeof(sun_data); -diff -Naur cyrus-imapd-2.3.9/ptclient/Makefile.in cyrus-imapd-2.3.9-autocreate.uncompiled/ptclient/Makefile.in ---- cyrus-imapd-2.3.9/ptclient/Makefile.in 2006-11-30 19:11:24.000000000 +0200 -+++ cyrus-imapd-2.3.9-autocreate.uncompiled/ptclient/Makefile.in 2007-08-21 14:59:22.000000000 +0300 -@@ -57,10 +57,11 @@ - AFS_LDFLAGS = @AFS_LDFLAGS@ @COM_ERR_LDFLAGS@ - AFS_LIBS = @AFS_LIBS@ - IMAP_LIBS = @IMAP_LIBS@ @LIB_RT@ -+SIEVE_LIBS = @SIEVE_LIBS@ - LIBS = $(IMAP_LIBS) @COM_ERR_LIBS@ - LIB_SASL = @LIB_SASL@ - LIB_WRAP = @LIB_WRAP@ --DEPLIBS = ../imap/libimap.a ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ -+DEPLIBS = ../imap/libimap.a $(SIEVE_LIBS) ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ - UTIL_LIBS = ../imap/mutex_fake.o ../imap/cli_fatal.o - - LDAP_LIBS=@LDAP_LIBS@ diff --git a/cyrus-imapd-2.3.9-autosieve-0.6.0.diff b/cyrus-imapd-2.3.9-autosieve-0.6.0.diff deleted file mode 100644 index a8bb3f6..0000000 --- a/cyrus-imapd-2.3.9-autosieve-0.6.0.diff +++ /dev/null @@ -1,181 +0,0 @@ -diff -Naur cyrus-imapd-2.3.9/README.autosievefolder cyrus-imapd-2.3.9-autosieve.uncompiled/README.autosievefolder ---- cyrus-imapd-2.3.9/README.autosievefolder 1970-01-01 02:00:00.000000000 +0200 -+++ cyrus-imapd-2.3.9-autosieve.uncompiled/README.autosievefolder 2007-08-21 16:04:08.000000000 +0300 -@@ -0,0 +1,42 @@ -+Cyrus IMAP autosievefolder patch -+---------------------------------- -+ -+NOTE : This patch has been created at the University of Athens. For more info, as well -+as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr -+ -+ -+ When the lmtpd daemon receives an email message prior to delivering it to the -+INBOX folder of the user, checks if the user has specified sieve filters. If the -+user has specified sieve filters the filters are evaluated. If the message matches -+any of the filters the action that is specified in the filter is executed. If the action -+is FileInto it is stored in the subfolder specified in the filter. If the -+subfolder doesn't exist then the message is sent to the INBOX folder of the user. -+ -+ With this patch if the folder doesn't exist AND the name of the subfolder is -+specified in the autosievefolders option, OR the anysievefolder is set to -+yes in the cyrus-imap configuration file then the subfolder is created and the mail -+is stored there. -+ -+ -+Check the following options of the imapd.conf file -+================================================== -+ -+* anysievefolder : It must be "yes" in order to permit the autocreation of any -+INBOX subfolder requested by a sieve filter, through the "fileinto" action. (default = no) -+* autosievefolders : It is a "|" separated list of subfolders of INBOX that will be -+automatically created, if requested by a sieve filter, through the "fileinto" -+action. (default = null) -+ i.e. autosievefolders: Junk | Spam -+ -+WARNING: anysievefolder, takes precedence over autosievefolders . Which means that if -+anysievefolder is set to "yes", cyrus will create any INBOX subfolder requested, no-matter what the value of autosievefolders is. -+ -+ -+Things to be done -+================= -+ -+1. Support cyrus wildcards in the autosievefolders option. -+ -+ -+For more information and updates please visit http://email.uoa.gr/projects/cyrus/autosievefolder -+ -diff -Naur cyrus-imapd-2.3.9/imap/lmtp_sieve.c cyrus-imapd-2.3.9-autosieve.uncompiled/imap/lmtp_sieve.c ---- cyrus-imapd-2.3.9/imap/lmtp_sieve.c 2007-03-27 22:53:08.000000000 +0300 -+++ cyrus-imapd-2.3.9-autosieve.uncompiled/imap/lmtp_sieve.c 2007-08-21 16:04:08.000000000 +0300 -@@ -88,6 +88,9 @@ - struct auth_state *authstate; - } script_data_t; - -+static int autosieve_subfolder(char *userid, struct auth_state *auth_state, -+ char *subfolder, struct namespace *namespace); -+ - static char *make_sieve_db(const char *user) - { - static char buf[MAX_MAILBOX_PATH+1]; -@@ -484,7 +487,20 @@ - sd->username, mdata->notifyheader, - namebuf, quotaoverride, 0); - } -- -+ -+ if (ret == IMAP_MAILBOX_NONEXISTENT) { -+ /* if "plus" folder under INBOX, then try to create it */ -+ ret = autosieve_subfolder((char *) sd->username, sd->authstate, namebuf, mdata->namespace); -+ -+ /* Try to deliver the mail again. */ -+ if (!ret) -+ ret = deliver_mailbox(md->f, mdata->content, mdata->stage, md->size, -+ fc->imapflags->flag, fc->imapflags->nflags, -+ (char *) sd->username, sd->authstate, md->id, -+ sd->username, mdata->notifyheader, -+ namebuf, quotaoverride, 0); -+ } -+ - if (!ret) { - snmp_increment(SIEVE_FILEINTO, 1); - return SIEVE_OK; -@@ -936,3 +952,80 @@ - we'll do normal delivery */ - return r; - } -+ -+ -+#define SEP '|' -+ -+static int autosieve_subfolder(char *userid, struct auth_state *auth_state, -+ char *subfolder, struct namespace *namespace) -+{ -+ char option_name_external[MAX_MAILBOX_NAME + 1]; -+ char option_name_internal[MAX_MAILBOX_NAME + 1]; -+ const char *subf ; -+ char *p, *q, *next_subf; -+ int len, r = 0; -+ int createsievefolder = 0; -+ -+ /* Check if subfolder or userid are NULL */ -+ if(userid == NULL || subfolder == NULL) -+ return IMAP_MAILBOX_NONEXISTENT; -+ -+ syslog(LOG_DEBUG, "autosievefolder: autosieve_subfolder() was called for user %s, folder %s", -+ userid, subfolder); -+ -+ if (config_getswitch(IMAPOPT_ANYSIEVEFOLDER)) { -+ createsievefolder = 1; -+ } else if ((subf = config_getstring(IMAPOPT_AUTOSIEVEFOLDERS)) != NULL) { -+ /* Roll through subf */ -+ next_subf = (char *) subf; -+ while (*next_subf) { -+ for (p = next_subf ; isspace((int) *p) || *p == SEP ; p++); -+ for (next_subf = p ; *next_subf && *next_subf != SEP ; next_subf++); -+ for (q = next_subf ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--); -+ -+ if (!*p) continue; -+ -+ len = q - p + 1; -+ /* -+ * This is a preliminary length check based on the assumption -+ * that the *final* internal format will be something -+ * like user.userid.subfolder(s). -+ */ -+ if (len > sizeof(option_name_external) - strlen(userid) - 5) -+ return IMAP_MAILBOX_BADNAME; -+ -+ strlcpy(option_name_external, namespace->prefix[NAMESPACE_INBOX], sizeof(option_name_external)); -+ strncat(option_name_external, p, len); -+ -+ /* -+ * Transform the option folder name to internal namespace and compare it -+ * with what must be created. -+ */ -+ r = namespace->mboxname_tointernal(namespace, option_name_external, userid, option_name_internal); -+ if (r) continue; -+ -+ if (!strcmp(option_name_internal, subfolder)) { -+ createsievefolder = 1; -+ break; -+ } -+ } -+ } -+ -+ if (createsievefolder) { -+ /* Folder is already in internal namespace format */ -+ r = mboxlist_createmailbox(subfolder, MAILBOX_FORMAT_NORMAL, NULL, -+ 1, userid, auth_state, 0, 0, 0); -+ if (!r) { -+ mboxlist_changesub(subfolder, userid, auth_state, 1, 1); -+ syslog(LOG_DEBUG, "autosievefolder: User %s, folder %s creation succeeded", -+ userid, subfolder); -+ return 0; -+ } else { -+ syslog(LOG_ERR, "autosievefolder: User %s, folder %s creation failed. %s", -+ userid, subfolder,error_message(r)); -+ return r; -+ } -+ } else -+ return IMAP_MAILBOX_NONEXISTENT; -+} -+ -diff -Naur cyrus-imapd-2.3.9/lib/imapoptions cyrus-imapd-2.3.9-autosieve.uncompiled/lib/imapoptions ---- cyrus-imapd-2.3.9/lib/imapoptions 2007-03-30 21:51:02.000000000 +0300 -+++ cyrus-imapd-2.3.9-autosieve.uncompiled/lib/imapoptions 2007-08-21 16:04:08.000000000 +0300 -@@ -884,6 +884,15 @@ - /* If enabled, lmtpd will look for Sieve scripts in user's home - directories: ~user/.sieve. */ - -+{ "anysievefolder", 0, SWITCH } -+/* It must be "yes" in order to permit the autocreation of any INBOX subfolder -+ requested by a sieve filter, through the "fileinto" action. (default = no) */ -+ -+{ "autosievefolders", NULL, STRING } -+/* It is a "|" separated list of subfolders of INBOX that will be automatically created, -+ if requested by a sieve filter, through the "fileinto" action. (default = null) -+ i.e. autosievefolders: Junk | Spam */ -+ - { "singleinstancestore", 1, SWITCH } - /* If enabled, imapd, lmtpd and nntpd attempt to only write one copy - of a message per partition and create hard links, resulting in a diff --git a/cyrus-imapd-2.3.9-getgrouplist.patch b/cyrus-imapd-2.3.9-getgrouplist.patch deleted file mode 100644 index 7201eb7..0000000 --- a/cyrus-imapd-2.3.9-getgrouplist.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- cyrus/lib/auth_unix.c 2007/02/13 16:42:49 1.41 -+++ cyrus/lib/auth_unix.c 2007/09/17 14:36:40 1.45 -@@ -41,7 +41,7 @@ - */ - - /* -- * $Id: auth_unix.c,v 1.41 2007/02/13 16:42:49 murch Exp $ -+ * $Id: auth_unix.c,v 1.45 2007/09/17 14:36:40 murch Exp $ - */ - - #include -@@ -224,6 +224,10 @@ static struct auth_state *mynewstate(con - struct passwd *pwd; - struct group *grp; - char **mem; -+#ifdef HAVE_GETGROUPLIST -+ gid_t gid, *groupids = NULL; -+ int ret, ngroups = 0; -+#endif - - identifier = mycanonifyid(identifier, 0); - if (!identifier) return 0; -@@ -239,7 +243,48 @@ static struct auth_state *mynewstate(con - return newstate; - - pwd = getpwnam(identifier); -- -+ -+#ifdef HAVE_GETGROUPLIST -+ gid = pwd ? pwd->pw_gid : (gid_t) -1; -+ -+ /* get number of groups user is member of into ngroups */ -+ getgrouplist(identifier, gid, NULL, &ngroups); -+ -+ /* get the actual group ids */ -+ do { -+ groupids = (gid_t *)xrealloc((gid_t *)groupids, -+ ngroups * sizeof(gid_t)); -+ -+ newstate->ngroups = ngroups; /* copy of ngroups for comparision */ -+ ret = getgrouplist(identifier, gid, groupids, &ngroups); -+ /* -+ * This is tricky. We do this as long as getgrouplist tells us to -+ * realloc _and_ the number of groups changes. It tells us to realloc -+ * also in the case of failure... -+ */ -+ } while (ret != -1 && ngroups != newstate->ngroups); -+ -+ if (ret == -1) { -+ newstate->ngroups = 0; -+ newstate->group = NULL; -+ goto err; -+ } -+ -+ newstate->ngroups = 0; -+ newstate->group = (char **)xmalloc(ngroups * sizeof(char *)); -+ while (ngroups--) { -+ if (pwd || groupids[ngroups] != gid) { -+ if ((grp = getgrgid(groupids[ngroups]))) { -+ newstate->ngroups++; -+ newstate->group[newstate->ngroups-1] = xstrdup(grp->gr_name); -+ } -+ } -+ } -+ -+err: -+ if (groupids) free(groupids); -+ -+#else /* !HAVE_GETGROUPLIST */ - setgrent(); - while ((grp = getgrent())) { - for (mem = grp->gr_mem; *mem; mem++) { -@@ -254,6 +299,8 @@ static struct auth_state *mynewstate(con - } - } - endgrent(); -+#endif /* HAVE_GETGROUPLIST */ -+ - return newstate; - } - diff --git a/cyrus-imapd-2.3.9-implicitdecl.patch b/cyrus-imapd-2.3.9-implicitdecl.patch deleted file mode 100644 index f999e57..0000000 --- a/cyrus-imapd-2.3.9-implicitdecl.patch +++ /dev/null @@ -1,282 +0,0 @@ ---- cyrus-imapd-2.3.9/imap/tls_prune.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/tls_prune.c 2007-09-18 15:48:46.000000000 +0200 -@@ -49,6 +49,7 @@ - - #include "exitcodes.h" - #include "global.h" -+#include "util.h" - #include "tls.h" - #include "xmalloc.h" - ---- cyrus-imapd-2.3.9/imap/sync_client.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/sync_client.c 2007-09-18 15:39:44.000000000 +0200 -@@ -69,6 +69,8 @@ - #include "mailbox.h" - #include "quota.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "acl.h" - #include "seen.h" - #include "mboxname.h" ---- cyrus-imapd-2.3.9/imap/protocol.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/protocol.c 2007-09-18 15:39:09.000000000 +0200 -@@ -49,6 +49,8 @@ - - #include "protocol.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - static char *imap_parsemechlist(const char *str, struct protocol_t *prot) - { ---- cyrus-imapd-2.3.9/imap/ipurge.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/ipurge.c 2007-09-18 15:48:26.000000000 +0200 -@@ -61,6 +61,7 @@ - - /* cyrus includes */ - #include "global.h" -+#include "util.h" - #include "sysexits.h" - #include "exitcodes.h" - #include "imap_err.h" ---- cyrus-imapd-2.3.9/imap/cyrdump.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/cyrdump.c 2007-09-18 15:48:30.000000000 +0200 -@@ -54,6 +54,7 @@ - #include "assert.h" - #include "exitcodes.h" - #include "global.h" -+#include "util.h" - #include "imapd.h" - #include "imap_err.h" - #include "imapurl.h" ---- cyrus-imapd-2.3.9/imap/fetchnews.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/fetchnews.c 2007-09-18 15:48:50.000000000 +0200 -@@ -60,10 +60,13 @@ - #include "cyrusdb.h" - #include "exitcodes.h" - #include "global.h" -+#include "util.h" - #include "gmtoff.h" - #include "lock.h" - #include "prot.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - /* global state */ - const int config_need_data = 0; ---- cyrus-imapd-2.3.9/imap/sync_server.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/sync_server.c 2007-09-18 15:40:02.000000000 +0200 -@@ -94,6 +94,8 @@ - #include "util.h" - #include "version.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - #include "sync_support.h" - #include "sync_commit.h" ---- cyrus-imapd-2.3.9/imap/ctl_mboxlist.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/ctl_mboxlist.c 2007-09-18 15:48:35.000000000 +0200 -@@ -77,6 +77,7 @@ - #include "exitcodes.h" - #include "imap_err.h" - #include "global.h" -+#include "util.h" - #include "libcyr_cfg.h" - #include "mboxlist.h" - #include "mupdate.h" ---- cyrus-imapd-2.3.9/imap/sync_support.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/sync_support.c 2007-09-18 15:39:55.000000000 +0200 -@@ -71,6 +71,8 @@ - #include "mailbox.h" - #include "quota.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "acl.h" - #include "seen.h" - #include "mboxname.h" ---- cyrus-imapd-2.3.9/imap/squatter.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/squatter.c 2007-09-18 15:48:39.000000000 +0200 -@@ -84,6 +84,7 @@ - #include "assert.h" - #include "mboxlist.h" - #include "global.h" -+#include "util.h" - #include "exitcodes.h" - #include "imap_err.h" - #include "mailbox.h" ---- cyrus-imapd-2.3.9/imap/autosieve.c.implicitdecl 2007-09-18 15:42:01.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/autosieve.c 2007-09-18 15:39:14.000000000 +0200 -@@ -19,6 +19,9 @@ - - #include "global.h" - #include "util.h" -+#include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "mailbox.h" - #include "imap_err.h" - #include "sieve_interface.h" ---- cyrus-imapd-2.3.9/imap/arbitron.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/arbitron.c 2007-09-18 15:48:43.000000000 +0200 -@@ -59,6 +59,7 @@ - - #include "assert.h" - #include "global.h" -+#include "util.h" - #include "exitcodes.h" - #include "hash.h" - #include "imap_err.h" ---- cyrus-imapd-2.3.9/imap/mupdate.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/mupdate.c 2007-09-18 15:39:34.000000000 +0200 -@@ -87,6 +87,8 @@ - #include "util.h" - #include "version.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - /* Sent to clients that we can't accept a connection for. */ - static const char SERVER_UNABLE_STRING[] = "* BYE \"Server Unable\"\r\n"; ---- cyrus-imapd-2.3.9/imap/make_md5.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/make_md5.c 2007-09-18 15:48:54.000000000 +0200 -@@ -16,6 +16,7 @@ - #include - - #include "global.h" -+#include "util.h" - #include "assert.h" - #include "mboxlist.h" - #include "exitcodes.h" ---- cyrus-imapd-2.3.9/imap/sync_commit.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/sync_commit.c 2007-09-18 15:40:08.000000000 +0200 -@@ -69,6 +69,8 @@ - #include "mailbox.h" - #include "quota.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "acl.h" - #include "seen.h" - #include "mboxname.h" ---- cyrus-imapd-2.3.9/imap/compile_sieve.c.implicitdecl 2007-09-18 15:27:37.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/compile_sieve.c 2007-09-18 15:27:48.000000000 +0200 -@@ -20,6 +20,7 @@ - #include "global.h" - - #include "util.h" -+#include "xmalloc.h" - #include "mailbox.h" - #include "imap_err.h" - #include "sieve_interface.h" ---- cyrus-imapd-2.3.9/timsieved/timsieved.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/timsieved/timsieved.c 2007-09-18 15:40:35.000000000 +0200 -@@ -73,6 +73,8 @@ - #include "prot.h" - #include "libconfig.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "exitcodes.h" - #include "iptostring.h" - #include "global.h" ---- cyrus-imapd-2.3.9/timsieved/actions.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/timsieved/actions.c 2007-09-18 15:40:25.000000000 +0200 -@@ -69,6 +69,8 @@ - #include "global.h" - #include "libconfig.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "sieve_interface.h" - - #include "codes.h" ---- cyrus-imapd-2.3.9/timsieved/parser.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/timsieved/parser.c 2007-09-18 15:40:41.000000000 +0200 -@@ -64,6 +64,8 @@ - #include "mboxname.h" - #include "mboxlist.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - #include "prot.h" - #include "tls.h" - #include "lex.h" ---- cyrus-imapd-2.3.9/master/cyrusMasterMIB.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/master/cyrusMasterMIB.c 2007-09-18 15:39:06.000000000 +0200 -@@ -52,6 +52,8 @@ - - #include "master.h" - #include "../imap/version.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - /* - * cyrusMasterMIB_variables_oid: ---- cyrus-imapd-2.3.9/sieve/interp.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/sieve/interp.c 2007-09-18 15:38:40.000000000 +0200 -@@ -33,6 +33,8 @@ - #include - - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - #include "sieve_interface.h" - #include "interp.h" ---- cyrus-imapd-2.3.9/sieve/addr.y.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/sieve/addr.y 2007-09-18 15:38:45.000000000 +0200 -@@ -37,6 +37,8 @@ - #include "addr.h" - #include "script.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - int yyerror(char *msg); - extern int yylex(void); ---- cyrus-imapd-2.3.9/imtest/imtest.c.implicitdecl 2007-09-18 15:36:52.000000000 +0200 -+++ cyrus-imapd-2.3.9/imtest/imtest.c 2007-09-18 15:40:14.000000000 +0200 -@@ -82,6 +82,8 @@ - #include "imparse.h" - #include "iptostring.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - #ifdef HAVE_SSL - #include ---- cyrus-imapd-2.3.9/ptclient/ptexpire.c.implicitdecl 2007-09-18 15:47:55.000000000 +0200 -+++ cyrus-imapd-2.3.9/ptclient/ptexpire.c 2007-09-18 15:48:57.000000000 +0200 -@@ -65,6 +65,7 @@ - #include "cyrusdb.h" - #include "exitcodes.h" - #include "global.h" -+#include "util.h" - #include "libconfig.h" - #include "lock.h" - #include "xmalloc.h" ---- cyrus-imapd-2.3.9/ptclient/ldap.c.implicitdecl 2007-09-18 15:49:48.000000000 +0200 -+++ cyrus-imapd-2.3.9/ptclient/ldap.c 2007-09-18 15:40:19.000000000 +0200 -@@ -61,6 +61,9 @@ - #include - #include - -+/* Functions like ldap_bind() have been deprecated in OpenLDAP 2.3 */ -+#define LDAP_DEPRECATED 1 -+ - #include - #include - -@@ -74,6 +77,8 @@ - #include "auth_pts.h" - #include "strhash.h" - #include "xmalloc.h" -+#include "xstrlcpy.h" -+#include "xstrlcat.h" - - /* xxx this just uses the UNIX canonicalization semantics, which is - * most likely wrong */ diff --git a/cyrus-imapd-2.3.9-myfatal.patch b/cyrus-imapd-2.3.9-myfatal.patch deleted file mode 100644 index 340811c..0000000 --- a/cyrus-imapd-2.3.9-myfatal.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- cyrus-imapd-2.3.9/imap/compile_sieve.c.myfatal 2007-09-23 16:13:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/compile_sieve.c 2007-09-23 16:54:54.000000000 +0200 -@@ -37,7 +37,7 @@ - - static int is_script_parsable(FILE *stream, char **errstr, sieve_script_t **ret); - --static void fatal(const char *s, int code) -+static void my_fatal(const char *s, int code) - { - printf("Fatal error: %s (%d)\r\n", s, code); - -@@ -68,7 +68,7 @@ - extern char *optarg; - char sieve_tmpname[MAX_MAILBOX_NAME+1]; - -- if (geteuid() == 0) fatal("must run as the Cyrus user", EC_USAGE); -+ if (geteuid() == 0) my_fatal("must run as the Cyrus user", EC_USAGE); - - while((opt = getopt(argc, argv, "C:i:o:")) != EOF) { - switch (opt) { -@@ -218,7 +218,7 @@ - /* to make larry's stupid functions happy :) */ - static void foo(void) - { -- fatal("stub function called", 0); -+ my_fatal("stub function called", 0); - } - - extern sieve_vacation_t vacation2;/* = { -@@ -234,7 +234,7 @@ - void *message_context __attribute__((unused)), - const char **errmsg __attribute__((unused))) - { -- fatal("stub function called", 0); -+ my_fatal("stub function called", 0); - return SIEVE_FAIL; - } - ---- cyrus-imapd-2.3.9/imap/autosieve.c.myfatal 2007-09-23 16:13:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/autosieve.c 2007-09-23 16:37:27.000000000 +0200 -@@ -35,7 +35,7 @@ - static int get_script_dir(char *sieve_script_dir, size_t buflen, char *userid, const char *sieve_dir); - int autoadd_sieve(char *userid, const char *source_script); - --static void fatal(const char *s, int code); -+static void my_fatal(const char *s, int code); - static void foo(void); - static int sieve_notify(void *ac __attribute__((unused)), - void *interp_context __attribute__((unused)), -@@ -441,7 +441,7 @@ - return 0; - } - --static void fatal(const char *s, int code) -+static void my_fatal(const char *s, int code) - { - printf("Fatal error: %s (%d)\r\n", s, code); - exit(1); -@@ -450,7 +450,7 @@ - /* to make larry's stupid functions happy :) */ - static void foo(void) - { -- fatal("stub function called", 0); -+ my_fatal("stub function called", 0); - } - - static int sieve_notify(void *ac __attribute__((unused)), -@@ -459,7 +459,7 @@ - void *message_context __attribute__((unused)), - const char **errmsg __attribute__((unused))) - { -- fatal("stub function called", 0); -+ my_fatal("stub function called", 0); - return SIEVE_FAIL; - } - diff --git a/cyrus-imapd-2.3.9-openmacro.patch b/cyrus-imapd-2.3.9-openmacro.patch deleted file mode 100644 index 43093e9..0000000 --- a/cyrus-imapd-2.3.9-openmacro.patch +++ /dev/null @@ -1,563 +0,0 @@ ---- cyrus-imapd-2.3.9/imap/quota_db.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/quota_db.c 2007-08-14 16:31:48.000000000 +0200 -@@ -251,7 +251,7 @@ - strlcat(fname, FNAME_QUOTADB, fname_len); - } - -- ret = QDB->open(fname, CYRUSDB_CREATE, &qdb); -+ ret = (QDB->open)(fname, CYRUSDB_CREATE, &qdb); - if (ret != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(ret)); -@@ -270,7 +270,7 @@ - int r; - - if (quota_dbopen) { -- r = QDB->close(qdb); -+ r = (QDB->close)(qdb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing quotas: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/imap/seen_bigdb.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/seen_bigdb.c 2007-08-14 16:32:03.000000000 +0200 -@@ -104,7 +104,7 @@ - strcpy(fname, config_dir); - strcat(fname, FNAME_SEENDB); - -- r = DB->open(fname, CYRUSDB_CREATE, &bigdb); -+ r = (DB->open)(fname, CYRUSDB_CREATE, &bigdb); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(r)); -@@ -385,7 +385,7 @@ - int r; - - if (seen_inited) { -- r = DB->close(bigdb); -+ r = (DB->close)(bigdb); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: closing seen database: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/imap/mboxkey.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/mboxkey.c 2007-08-14 16:31:01.000000000 +0200 -@@ -150,7 +150,7 @@ - /* otherwise, close the existing database */ - if (mboxkeydb) { - abortcurrent(mboxkeydb); -- r = DB->close(mboxkeydb->db); -+ r = (DB->close)(mboxkeydb->db); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing mboxkeydb: %s", - cyrusdb_strerror(r)); -@@ -164,7 +164,7 @@ - - /* open the mboxkeydb corresponding to user */ - fname = mboxkey_getpath(user); -- r = DB->open(fname, (flags & MBOXKEY_CREATE) ? CYRUSDB_CREATE : 0, -+ r = (DB->open)(fname, (flags & MBOXKEY_CREATE) ? CYRUSDB_CREATE : 0, - &mboxkeydb->db); - if (r != 0) { - int level = (flags & MBOXKEY_CREATE) ? LOG_ERR : LOG_DEBUG; -@@ -325,7 +325,7 @@ - - /* free the old database hanging around */ - abortcurrent(lastmboxkey); -- r = DB->close(lastmboxkey->db); -+ r = (DB->close)(lastmboxkey->db); - if (r != CYRUSDB_OK) { - syslog(LOG_ERR, "DBERROR: error closing lastmboxkey: %s", - cyrusdb_strerror(r)); -@@ -409,7 +409,7 @@ - - if (lastmboxkey) { - abortcurrent(lastmboxkey); -- r = DB->close(lastmboxkey->db); -+ r = (DB->close)(lastmboxkey->db); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing lastmboxkey: %s", - cyrusdb_strerror(r)); -@@ -482,10 +482,10 @@ - struct mboxkey_merge_rock rock; - - /* xxx does this need to be CYRUSDB_CREATE? */ -- r = DB->open(tmpfile, CYRUSDB_CREATE, &tmp); -+ r = (DB->open)(tmpfile, CYRUSDB_CREATE, &tmp); - if(r) goto done; - -- r = DB->open(tgtfile, CYRUSDB_CREATE, &tgt); -+ r = (DB->open)(tgtfile, CYRUSDB_CREATE, &tgt); - if(r) goto done; - - rock.db = tgt; -@@ -498,8 +498,8 @@ - - done: - -- if(tgt) DB->close(tgt); -- if(tmp) DB->close(tmp); -+ if(tgt) (DB->close)(tgt); -+ if(tmp) (DB->close)(tmp); - - return r; - } ---- cyrus-imapd-2.3.9/imap/tls.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/tls.c 2007-08-14 16:33:15.000000000 +0200 -@@ -650,7 +650,7 @@ - strlcpy(dbdir, config_dir, sizeof(dbdir)); - strlcat(dbdir, FNAME_TLSSESSIONS, sizeof(dbdir)); - -- r = DB->open(dbdir, CYRUSDB_CREATE, &sessdb); -+ r = (DB->open)(dbdir, CYRUSDB_CREATE, &sessdb); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", - dbdir, cyrusdb_strerror(ret)); -@@ -931,7 +931,7 @@ - int r; - - if (tls_serverengine && sess_dbopen) { -- r = DB->close(sessdb); -+ r = (DB->close)(sessdb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing tlsdb: %s", - cyrusdb_strerror(r)); -@@ -1008,7 +1008,7 @@ - strlcpy(dbdir, config_dir, sizeof(dbdir)); - strlcat(dbdir, FNAME_TLSSESSIONS, sizeof(dbdir)); - -- ret = DB->open(dbdir, CYRUSDB_CREATE, &sessdb); -+ ret = (DB->open)(dbdir, CYRUSDB_CREATE, &sessdb); - if (ret != CYRUSDB_OK) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", - dbdir, cyrusdb_strerror(ret)); -@@ -1019,7 +1019,7 @@ - sess_dbopen = 1; - prock.count = prock.deletions = 0; - DB->foreach(sessdb, "", 0, &prune_p, &prune_cb, &prock, NULL); -- DB->close(sessdb); -+ (DB->close)(sessdb); - sessdb = NULL; - sess_dbopen = 0; - ---- cyrus-imapd-2.3.9/imap/duplicate.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/duplicate.c 2007-08-14 16:30:03.000000000 +0200 -@@ -105,7 +105,7 @@ - strcat(fname, FNAME_DELIVERDB); - } - -- r = DB->open(fname, CYRUSDB_CREATE, &dupdb); -+ r = (DB->open)(fname, CYRUSDB_CREATE, &dupdb); - if (r != 0) - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(r)); -@@ -395,7 +395,7 @@ - int r = 0; - - if (duplicate_dbopen) { -- r = DB->close(dupdb); -+ r = (DB->close)(dupdb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing deliverdb: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/imap/cvt_cyrusdb.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/cvt_cyrusdb.c 2007-08-14 16:29:32.000000000 +0200 -@@ -157,10 +157,10 @@ - printf("Converting from %s (%s) to %s (%s)\n", old_db, DB_OLD->name, - new_db, DB_NEW->name); - -- r = DB_OLD->open(old_db, 0, &odb); -+ r = (DB_OLD->open)(old_db, 0, &odb); - if(r != CYRUSDB_OK) - fatal("can't open old database", EC_TEMPFAIL); -- r = DB_NEW->open(new_db, CYRUSDB_CREATE, &ndb); -+ r = (DB_NEW->open)(new_db, CYRUSDB_CREATE, &ndb); - if(r != CYRUSDB_OK) - fatal("can't open new database", EC_TEMPFAIL); - -@@ -173,8 +173,8 @@ - fprintf(stderr, "Warning: apparently empty database converted.\n"); - - -- DB_OLD->close(odb); -- DB_NEW->close(ndb); -+ (DB_OLD->close)(odb); -+ (DB_NEW->close)(ndb); - - cyrus_done(); - ---- cyrus-imapd-2.3.9/imap/annotate.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/annotate.c 2007-08-14 16:28:42.000000000 +0200 -@@ -253,7 +253,7 @@ - strcat(fname, FNAME_ANNOTATIONS); - } - -- ret = DB->open(fname, CYRUSDB_CREATE, &anndb); -+ ret = (DB->open)(fname, CYRUSDB_CREATE, &anndb); - if (ret != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(ret)); -@@ -270,7 +270,7 @@ - int r; - - if (annotate_dbopen) { -- r = DB->close(anndb); -+ r = (DB->close)(anndb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing annotations: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/imap/arbitron.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/arbitron.c 2007-08-14 16:29:11.000000000 +0200 -@@ -419,14 +419,14 @@ - int r; - struct db *tmp = NULL; - -- r = DB->open(path, 0, &tmp); -+ r = (DB->open)(path, 0, &tmp); - if(r) goto done; - - DB->foreach(tmp, "", 0, process_user_p, process_user_cb, - (void *) user, NULL); - - done: -- if(tmp) DB->close(tmp); -+ if(tmp) (DB->close)(tmp); - } - - static int process_subs_cb(void *rockp __attribute__((unused)), -@@ -475,14 +475,14 @@ - int r; - struct db *tmp = NULL; - -- r = SUBDB->open(path, 0, &tmp); -+ r = (SUBDB->open)(path, 0, &tmp); - if(r) goto done; - - SUBDB->foreach(tmp, "", 0, process_subs_p, process_subs_cb, - (void *) user, NULL); - - done: -- if(tmp) SUBDB->close(tmp); -+ if(tmp) (SUBDB->close)(tmp); - } - - void report_users(struct user_list *u) ---- cyrus-imapd-2.3.9/imap/mboxlist.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/mboxlist.c 2007-08-14 16:31:28.000000000 +0200 -@@ -2746,7 +2746,7 @@ - flags |= CYRUSDB_MBOXSORT; - } - -- ret = DB->open(fname, flags, &mbdb); -+ ret = (DB->open)(fname, flags, &mbdb); - if (ret != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(ret)); -@@ -2765,7 +2765,7 @@ - int r; - - if (mboxlist_dbopen) { -- r = DB->close(mbdb); -+ r = (DB->close)(mbdb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing mailboxes: %s", - cyrusdb_strerror(r)); -@@ -2825,7 +2825,7 @@ - flags |= CYRUSDB_MBOXSORT; - } - -- r = SUBDB->open(subsfname, flags, ret); -+ r = (SUBDB->open)(subsfname, flags, ret); - if (r != CYRUSDB_OK) { - r = IMAP_IOERROR; - } -@@ -2839,7 +2839,7 @@ - */ - static void mboxlist_closesubs(struct db *sub) - { -- SUBDB->close(sub); -+ (SUBDB->close)(sub); - } - - /* ---- cyrus-imapd-2.3.9/imap/cyr_dbtool.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/cyr_dbtool.c 2007-08-14 16:29:52.000000000 +0200 -@@ -203,7 +203,7 @@ - cyrus_init(alt_config, "cyr_dbtool", 0); - - -- r = DB_OLD->open(old_db, db_flags, &odb); -+ r = (DB_OLD->open)(old_db, db_flags, &odb); - if(r != CYRUSDB_OK) - fatal("can't open database", EC_TEMPFAIL); - -@@ -250,7 +250,7 @@ - printf("Unknown action %s\n", action); - } - -- DB_OLD->close(odb); -+ (DB_OLD->close)(odb); - - cyrus_done(); - ---- cyrus-imapd-2.3.9/imap/seen_db.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/seen_db.c 2007-08-14 16:32:46.000000000 +0200 -@@ -157,7 +157,7 @@ - /* otherwise, close the existing database */ - if (seendb) { - abortcurrent(seendb); -- r = DB->close(seendb->db); -+ r = (DB->close)(seendb->db); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing seendb: %s", - cyrusdb_strerror(r)); -@@ -170,7 +170,7 @@ - - /* open the seendb corresponding to user */ - fname = seen_getpath(user); -- r = DB->open(fname, (flags & SEEN_CREATE) ? CYRUSDB_CREATE : 0, -+ r = (DB->open)(fname, (flags & SEEN_CREATE) ? CYRUSDB_CREATE : 0, - &seendb->db); - if (r != 0) { - int level = (flags & SEEN_CREATE) ? LOG_ERR : LOG_DEBUG; -@@ -416,7 +416,7 @@ - - /* free the old database hanging around */ - abortcurrent(lastseen); -- r = DB->close(lastseen->db); -+ r = (DB->close)(lastseen->db); - if (r != CYRUSDB_OK) { - syslog(LOG_ERR, "DBERROR: error closing lastseen: %s", - cyrusdb_strerror(r)); -@@ -555,7 +555,7 @@ - - if (lastseen) { - abortcurrent(lastseen); -- r = DB->close(lastseen->db); -+ r = (DB->close)(lastseen->db); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing lastseen: %s", - cyrusdb_strerror(r)); -@@ -653,10 +653,10 @@ - struct seen_merge_rock rock; - - /* xxx does this need to be CYRUSDB_CREATE? */ -- r = DB->open(tmpfile, CYRUSDB_CREATE, &tmp); -+ r = (DB->open)(tmpfile, CYRUSDB_CREATE, &tmp); - if(r) goto done; - -- r = DB->open(tgtfile, CYRUSDB_CREATE, &tgt); -+ r = (DB->open)(tgtfile, CYRUSDB_CREATE, &tgt); - if(r) goto done; - - rock.db = tgt; -@@ -669,8 +669,8 @@ - - done: - -- if(tgt) DB->close(tgt); -- if(tmp) DB->close(tmp); -+ if(tgt) (DB->close)(tgt); -+ if(tmp) (DB->close)(tmp); - - return r; - } ---- cyrus-imapd-2.3.9/imap/fetchnews.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/imap/fetchnews.c 2007-08-14 16:30:14.000000000 +0200 -@@ -94,7 +94,7 @@ - strcat(fname, FNAME_NEWSRCDB); - } - -- r = DB->open(fname, CYRUSDB_CREATE, &newsrc_db); -+ r = (DB->open)(fname, CYRUSDB_CREATE, &newsrc_db); - if (r != 0) - syslog(LOG_ERR, "DBERROR: opening %s: %s", fname, - cyrusdb_strerror(r)); -@@ -112,7 +112,7 @@ - int r = 0; - - if (newsrc_dbopen) { -- r = DB->close(newsrc_db); -+ r = (DB->close)(newsrc_db); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing fetchnews.db: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/lib/auth_pts.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/lib/auth_pts.c 2007-08-14 16:33:28.000000000 +0200 -@@ -359,7 +359,7 @@ - - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); -- r = the_ptscache_db->open(fnamebuf, CYRUSDB_CREATE, &ptdb); -+ r = (the_ptscache_db->open)(fnamebuf, CYRUSDB_CREATE, &ptdb); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fnamebuf, - cyrusdb_strerror(ret)); -@@ -501,7 +501,7 @@ - } - - /* close and unlock the database */ -- the_ptscache_db->close(ptdb); -+ (the_ptscache_db->close)(ptdb); - - return rc; - } ---- cyrus-imapd-2.3.9/lib/test/rnddb.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/lib/test/rnddb.c 2007-08-14 16:34:50.000000000 +0200 -@@ -133,7 +133,7 @@ - srand(atoi(argv[2])); - } - -- TRY(DB->open("scratch", &db)); -+ TRY((DB->open)("scratch", &db)); - - if (DB->consistent) { - TRY(DB->consistent(db)); -@@ -291,7 +291,7 @@ - #endif - } - -- TRY(DB->close(db)); -+ TRY((DB->close)(db)); - TRY(DB->done()); - - do_report(); ---- cyrus-imapd-2.3.9/lib/test/cyrusdb.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/lib/test/cyrusdb.c 2007-08-14 16:34:37.000000000 +0200 -@@ -70,15 +70,15 @@ - char *fname = buf + 5; - - if (db) { /* close it */ -- TRY(DB->close(db)); -+ TRY((DB->close)(db)); - } -- TRY(DB->open(fname, 1, &db)); -+ TRY((DB->open)(fname, 1, &db)); - - printf("ok\n"); - } else if (!db) { - TRY(db == NULL); - } else if (!strncasecmp(buf, "close", 5)) { -- TRY(DB->close(db)); -+ TRY((DB->close)(db)); - db = NULL; - printf("ok\n"); - } else if (!strncasecmp(buf, "put ", 4)) { ---- cyrus-imapd-2.3.9/lib/cyrusdb_berkeley.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/lib/cyrusdb_berkeley.c 2007-08-14 16:34:19.000000000 +0200 -@@ -212,7 +212,7 @@ - r = dbenv->set_cachesize(dbenv, 0, opt * 1024, 0); - if (r) { - dbenv->err(dbenv, r, "set_cachesize"); -- dbenv->close(dbenv, 0); -+ (dbenv->close)(dbenv, 0); - syslog(LOG_ERR, "DBERROR: set_cachesize(): %s", db_strerror(r)); - return CYRUSDB_IOERROR; - } -@@ -223,9 +223,9 @@ - flags |= DB_INIT_LOCK | DB_INIT_MPOOL | - DB_INIT_LOG | DB_INIT_TXN; - #if (DB_VERSION_MAJOR > 3) || ((DB_VERSION_MAJOR == 3) && (DB_VERSION_MINOR > 0)) -- r = dbenv->open(dbenv, dbdir, flags, 0644); -+ r = (dbenv->open)(dbenv, dbdir, flags, 0644); - #else -- r = dbenv->open(dbenv, dbdir, NULL, flags, 0644); -+ r = (dbenv->open)(dbenv, dbdir, NULL, flags, 0644); - #endif - if (r) { - if (do_retry && (r == ENOENT)) { -@@ -264,7 +264,7 @@ - - if (--dbinit) return 0; - -- r = dbenv->close(dbenv, 0); -+ r = (dbenv->close)(dbenv, 0); - dbinit = 0; - if (r) { - syslog(LOG_ERR, "DBERROR: error exiting application: %s", -@@ -412,15 +412,15 @@ - if (flags & CYRUSDB_MBOXSORT) db->set_bt_compare(db, mbox_compar); - - #if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1 -- r = db->open(db, NULL, fname, NULL, type, dbflags | DB_AUTO_COMMIT, 0664); -+ r = (db->open)(db, NULL, fname, NULL, type, dbflags | DB_AUTO_COMMIT, 0664); - #else -- r = db->open(db, fname, NULL, type, dbflags, 0664); -+ r = (db->open)(db, fname, NULL, type, dbflags, 0664); - #endif - - if (r != 0) { - int level = (flags & CYRUSDB_CREATE) ? LOG_ERR : LOG_DEBUG; - syslog(level, "DBERROR: opening %s: %s", fname, db_strerror(r)); -- r = db->close(db, DB_NOSYNC); -+ r = (db->close)(db, DB_NOSYNC); - if (r != 0) { - syslog(level, "DBERROR: closing %s: %s", fname, db_strerror(r)); - } -@@ -450,7 +450,7 @@ - assert(dbinit && db); - - /* since we're using txns, we can supply DB_NOSYNC */ -- r = a->close(a, DB_NOSYNC); -+ r = (a->close)(a, DB_NOSYNC); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: error closing: %s", db_strerror(r)); - r = CYRUSDB_IOERROR; ---- cyrus-imapd-2.3.9/ptclient/ptloader.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/ptclient/ptloader.c 2007-08-14 16:35:25.000000000 +0200 -@@ -167,7 +167,7 @@ - - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); -- r = DB->open(fnamebuf, CYRUSDB_CREATE, &ptsdb); -+ r = (DB->open)(fnamebuf, CYRUSDB_CREATE, &ptsdb); - if (r != 0) { - syslog(LOG_ERR, "DBERROR: opening %s: %s", fnamebuf, - cyrusdb_strerror(ret)); -@@ -184,7 +184,7 @@ - { - int r; - -- r = DB->close(ptsdb); -+ r = (DB->close)(ptsdb); - if (r) { - syslog(LOG_ERR, "DBERROR: error closing ptsdb: %s", - cyrusdb_strerror(r)); ---- cyrus-imapd-2.3.9/ptclient/ptdump.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/ptclient/ptdump.c 2007-08-14 16:35:02.000000000 +0200 -@@ -100,7 +100,7 @@ - /* open database */ - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); -- r = config_ptscache_db->open(fnamebuf, CYRUSDB_CREATE, &ptdb); -+ r = (config_ptscache_db->open)(fnamebuf, CYRUSDB_CREATE, &ptdb); - if(r != CYRUSDB_OK) { - fprintf(stderr,"error opening %s (%s)", fnamebuf, - cyrusdb_strerror(r)); -@@ -110,7 +110,7 @@ - /* iterate through db, wiping expired entries */ - config_ptscache_db->foreach(ptdb, "", 0, NULL, dump_cb, ptdb, NULL); - -- config_ptscache_db->close(ptdb); -+ (config_ptscache_db->close)(ptdb); - - cyrus_done(); - ---- cyrus-imapd-2.3.9/ptclient/ptexpire.c.openmacro 2007-08-14 16:21:29.000000000 +0200 -+++ cyrus-imapd-2.3.9/ptclient/ptexpire.c 2007-08-14 16:35:14.000000000 +0200 -@@ -148,7 +148,7 @@ - /* open database */ - strcpy(fnamebuf, config_dir); - strcat(fnamebuf, PTS_DBFIL); -- r = config_ptscache_db->open(fnamebuf, CYRUSDB_CREATE, &ptdb); -+ r = (config_ptscache_db->open)(fnamebuf, CYRUSDB_CREATE, &ptdb); - if(r != CYRUSDB_OK) { - syslog(LOG_ERR, "error opening %s (%s)", fnamebuf, - cyrusdb_strerror(r)); -@@ -158,7 +158,7 @@ - /* iterate through db, wiping expired entries */ - config_ptscache_db->foreach(ptdb, "", 0, expire_p, expire_cb, ptdb, NULL); - -- config_ptscache_db->close(ptdb); -+ (config_ptscache_db->close)(ptdb); - - cyrus_done(); - diff --git a/cyrus-imapd.spec b/cyrus-imapd.spec index 00d1e5e..4e4fdae 100644 --- a/cyrus-imapd.spec +++ b/cyrus-imapd.spec @@ -1,7 +1,7 @@ -%define upstream_ver 2.3.9 +%define upstream_ver 2.3.11 Name: cyrus-imapd -Version: 2.3.9 -Release: 12%{?dist} +Version: 2.3.11 +Release: 1%{?dist} # ********************** BUILD TIME OPTIONS START ********************** @@ -130,9 +130,9 @@ Source29: cyrus-imapd-sendmail-8.12.9-cyrusv2.m4 Source30: cyrus-imapd-README.contrib Source33: cyrus-imapd-README.skiplist_recovery Patch0: cyrus-imapd-2.2.12-no_transfig.patch -Patch1: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.9-autocreate-0.10-0.diff -Patch2: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.9-autosieve-0.6.0.diff -Patch3: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.9-rmquota+deletemailbox-0.2-1.diff +Patch1: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.11-autocreate-0.10-0.diff +Patch2: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.11-autosieve-0.6.0.diff +#Patch3: http://email.uoa.gr/download/cyrus/cyrus-imapd-2.3.9/cyrus-imapd-2.3.9-rmquota+deletemailbox-0.2-1.diff Patch4: http://servercc.oakton.edu/~jwade/cyrus/cyrus-imapd-2.1.3/cyrus-imapd-2.1.3-flock.patch Patch5: cyrus-imapd-2.2.12-munge8bit.patch Patch6: cyrus-imapd-2.1.16-getrlimit.patch @@ -147,13 +147,10 @@ Patch15: cyrus-imapd-2.3.1-make_md5_defaults.patch Patch16: cyrus-imapd-2.3.7-db4.5.patch Patch17: cyrus-imapd-2.3.7-makeinstallfix.patch Patch18: cyrus-imapd-2.3.7-krb4.patch -Patch19: cyrus-imapd-2.3.9-implicitdecl.patch -Patch20: cyrus-imapd-2.3.9-myfatal.patch # Patches >= 100 are / will be fixed in CVS Patch100: cyrus-imapd-2.3.1-make_md5.patch Patch101: cyrus-imapd-2.3.1-backend_sigsegv.patch Patch102: cyrus-imapd-2.3.1-replication_policycheck.patch -Patch103: cyrus-imapd-2.3.9-getgrouplist.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: autoconf >= 2.59 BuildRequires: cyrus-sasl-devel >= 2.1.15-1, perl, perl-devel, tcp_wrappers @@ -239,7 +236,7 @@ one running the server. %if %{AUTOCREATE} %patch1 -p1 -b .autocreate %patch2 -p1 -b .autosieve -%patch3 -p1 -b .rmquota +#%patch3 -p1 -b .rmquota %endif %patch4 -p1 -b .flock # superseded by upstream munge8bit support @@ -259,9 +256,6 @@ one running the server. #%patch16 -p1 -b .db4.5 #%patch17 -p1 -b .makeinstallfix %patch18 -p1 -b .krb4 -%patch19 -p1 -b .implicitdecl -%patch20 -p1 -b .myfatal -%patch103 -p1 -b .getgrouplist # fixed upstream #%patch100 -p1 -b .make_md5 # fixed upstream @@ -706,6 +700,7 @@ fi %attr(0755,root,root) %{_cyrexecdir}/cvt_cyrusdb %attr(0755,root,root) %{_cyrexecdir}/cyr_dbtool %attr(0755,root,root) %{_cyrexecdir}/cyr_expire +%attr(0755,root,root) %{_cyrexecdir}/cyr_synclog %attr(0755,root,root) %{_cyrexecdir}/cyrdump %attr(0755,root,root) %{_cyrexecdir}/cyrus-master %attr(0755,root,root) %{_cyrexecdir}/deliver @@ -715,6 +710,7 @@ fi %attr(0755,root,root) %{_cyrexecdir}/ipurge %attr(0755,root,root) %{_cyrexecdir}/lmtpd %attr(0755,root,root) %{_cyrexecdir}/lmtpproxyd +%attr(0755,root,root) %{_cyrexecdir}/make_sha1 %attr(0755,root,root) %{_cyrexecdir}/masssievec %attr(0755,root,root) %{_cyrexecdir}/mbexamine %attr(0755,root,root) %{_cyrexecdir}/mbpath @@ -808,6 +804,10 @@ fi %{_mandir}/man1/* %changelog +* Tue Mar 25 2008 Tomas Janousek - 2.3.11-1 +- update to latest upstream +- (temporarily) dropped the rmquota+deletemailbox patch (doesn't apply) + * Wed Mar 19 2008 Rex Dieter - 2.3.9-12 - cyrus-imapd conflicts with uw-imap (#222506)