]>
Commit | Line | Data |
---|---|---|
b40388bb MT |
1 | diff -Naur cyrus-imapd-2.2.12/README.autosievefolder cyrus-imapd-2.2.12-autosieve.uncompiled/README.autosievefolder |
2 | --- cyrus-imapd-2.2.12/README.autosievefolder 1970-01-01 02:00:00 +0200 | |
3 | +++ cyrus-imapd-2.2.12-autosieve.uncompiled/README.autosievefolder 2005-02-15 13:59:51 +0200 | |
4 | @@ -0,0 +1,42 @@ | |
5 | +Cyrus IMAP autosievefolder patch | |
6 | +---------------------------------- | |
7 | + | |
8 | +NOTE : This patch has been created at the University of Athens. For more info, as well | |
9 | +as more patches on Cyrus IMAPD server, please visit http://email.uoa.gr | |
10 | + | |
11 | + | |
12 | + When the lmtpd daemon receives an email message prior to delivering it to the | |
13 | +INBOX folder of the user, checks if the user has specified sieve filters. If the | |
14 | +user has specified sieve filters the filters are evaluated. If the message matches | |
15 | +any of the filters the action that is specified in the filter is executed. If the action | |
16 | +is FileInto it is stored in the subfolder specified in the filter. If the | |
17 | +subfolder doesn't exist then the message is sent to the INBOX folder of the user. | |
18 | + | |
19 | + With this patch if the folder doesn't exist AND the name of the subfolder is | |
20 | +specified in the autosievefolders option, OR the anysievefolder is set to | |
21 | +yes in the cyrus-imap configuration file then the subfolder is created and the mail | |
22 | +is stored there. | |
23 | + | |
24 | + | |
25 | +Check the following options of the imapd.conf file | |
26 | +================================================== | |
27 | + | |
28 | +* anysievefolder : It must be "yes" in order to permit the autocreation of any | |
29 | +INBOX subfolder requested by a sieve filter, through the "fileinto" action. (default = no) | |
30 | +* autosievefolders : It is a "|" separated list of subfolders of INBOX that will be | |
31 | +automatically created, if requested by a sieve filter, through the "fileinto" | |
32 | +action. (default = null) | |
33 | + i.e. autosievefolders: Junk | Spam | |
34 | + | |
35 | +WARNING: anysievefolder, takes precedence over autosievefolders . Which means that if | |
36 | +anysievefolder is set to "yes", cyrus will create any INBOX subfolder requested, no-matter what the value of autosievefolders is. | |
37 | + | |
38 | + | |
39 | +Things to be done | |
40 | +================= | |
41 | + | |
42 | +1. Support cyrus wildcards in the autosievefolders option. | |
43 | + | |
44 | + | |
45 | +For more information and updates please visit http://email.uoa.gr/projects/cyrus/autosievefolder | |
46 | + | |
47 | diff -Naur cyrus-imapd-2.2.12/imap/lmtp_sieve.c cyrus-imapd-2.2.12-autosieve.uncompiled/imap/lmtp_sieve.c | |
48 | --- cyrus-imapd-2.2.12/imap/lmtp_sieve.c 2004-06-01 16:47:16 +0300 | |
49 | +++ cyrus-imapd-2.2.12-autosieve.uncompiled/imap/lmtp_sieve.c 2005-02-15 13:59:51 +0200 | |
50 | @@ -72,6 +72,8 @@ | |
51 | #include "util.h" | |
52 | #include "version.h" | |
53 | #include "xmalloc.h" | |
54 | +#include "imap_err.h" | |
55 | + | |
56 | ||
57 | static int sieve_usehomedir = 0; | |
58 | static const char *sieve_dir = NULL; | |
59 | @@ -98,6 +100,9 @@ | |
60 | int quotaoverride, | |
61 | int acloverride); | |
62 | ||
63 | +static int autosieve_subfolder(char *userid, struct auth_state *auth_state, | |
64 | + char *subfolder, struct namespace *namespace); | |
65 | + | |
66 | static char *make_sieve_db(const char *user) | |
67 | { | |
68 | static char buf[MAX_MAILBOX_PATH+1]; | |
69 | @@ -312,6 +317,7 @@ | |
70 | } | |
71 | ||
72 | ||
73 | + | |
74 | static int sieve_redirect(void *ac, | |
75 | void *ic __attribute__((unused)), | |
76 | void *sc, void *mc, const char **errmsg) | |
77 | @@ -444,7 +450,18 @@ | |
78 | sd->username, mdata->notifyheader, | |
79 | namebuf, quotaoverride, 0); | |
80 | } | |
81 | - | |
82 | + if (ret == IMAP_MAILBOX_NONEXISTENT) { | |
83 | + /* if "plus" folder under INBOX, then try to create it */ | |
84 | + syslog(LOG_DEBUG, "calling autosieve folder for : %s", namebuf); | |
85 | + ret = autosieve_subfolder((char *) sd->username, sd->authstate, namebuf, mdata->namespace); | |
86 | + | |
87 | + if (!ret) | |
88 | + ret = deliver_mailbox(md->data, mdata->stage, md->size, | |
89 | + fc->imapflags->flag, fc->imapflags->nflags, | |
90 | + (char *) sd->username, sd->authstate, md->id, | |
91 | + sd->username, mdata->notifyheader, | |
92 | + namebuf, quotaoverride, 0); | |
93 | + } | |
94 | if (!ret) { | |
95 | snmp_increment(SIEVE_FILEINTO, 1); | |
96 | return SIEVE_OK; | |
97 | @@ -882,3 +899,77 @@ | |
98 | ||
99 | return r; | |
100 | } | |
101 | + | |
102 | + | |
103 | +#define SEP '|' | |
104 | + | |
105 | +static int autosieve_subfolder(char *userid, struct auth_state *auth_state, | |
106 | + char *subfolder, struct namespace *namespace) | |
107 | +{ | |
108 | + char option_name_external[MAX_MAILBOX_NAME + 1]; | |
109 | + char option_name_internal[MAX_MAILBOX_NAME + 1]; | |
110 | + const char *subf ; | |
111 | + char *p, *q, *next_subf; | |
112 | + int len, r = 0; | |
113 | + int createsievefolder = 0; | |
114 | + | |
115 | + /* Check if subfolder or userid are NULL */ | |
116 | + if(subfolder == NULL || userid == NULL) | |
117 | + return IMAP_MAILBOX_NONEXISTENT; | |
118 | + | |
119 | + if (config_getswitch(IMAPOPT_ANYSIEVEFOLDER)) | |
120 | + createsievefolder = 1; | |
121 | + else if ((subf = config_getstring(IMAPOPT_AUTOSIEVEFOLDERS)) != NULL) { | |
122 | + /* Roll through subf */ | |
123 | + next_subf = (char *) subf; | |
124 | + while (*next_subf) { | |
125 | + for (p = next_subf ; isspace((int) *p) || *p == SEP ; p++); | |
126 | + for (next_subf = p ; *next_subf && *next_subf != SEP ; next_subf++); | |
127 | + for (q = next_subf ; q > p && (isspace((int) *q) || *q == SEP || !*q); q--); | |
128 | + | |
129 | + if (!*p) continue; | |
130 | + | |
131 | + len = q - p + 1; | |
132 | + /* | |
133 | + * This is a preliminary length check based on the assumption | |
134 | + * that the *final* internal format will be something | |
135 | + * like user.userid.subfolder(s). | |
136 | + */ | |
137 | + if (len > sizeof(option_name_external) - strlen(userid) - 5) | |
138 | + return IMAP_MAILBOX_BADNAME; | |
139 | + | |
140 | + strlcpy(option_name_external, namespace->prefix[NAMESPACE_INBOX], sizeof(option_name_external)); | |
141 | + strncat(option_name_external, p, len); | |
142 | + | |
143 | + /* | |
144 | + * Transform the option folder name to internal namespace and compare it | |
145 | + * with what must be created. | |
146 | + */ | |
147 | + r = namespace->mboxname_tointernal(namespace, option_name_external, userid, option_name_internal); | |
148 | + if (r) continue; | |
149 | + | |
150 | + if (!strcmp(option_name_internal, subfolder)) { | |
151 | + createsievefolder = 1; | |
152 | + break; | |
153 | + } | |
154 | + } | |
155 | + } | |
156 | + | |
157 | + if (createsievefolder) { | |
158 | + /* Folder is already in internal namespace format */ | |
159 | + r = mboxlist_createmailbox(subfolder, MAILBOX_FORMAT_NORMAL, NULL, | |
160 | + 1, userid, auth_state, 0, 0, 0); | |
161 | + if (!r) { | |
162 | + mboxlist_changesub(subfolder, userid, auth_state, 1, 1); | |
163 | + syslog(LOG_DEBUG, "autosievefolder: User %s, folder %s creation succeeded.", | |
164 | + userid, subfolder); | |
165 | + return 0; | |
166 | + } else { | |
167 | + syslog(LOG_ERR, "autosievefolder: User %s, folder %s creation failed. %s", | |
168 | + userid, subfolder,error_message(r)); | |
169 | + return r; | |
170 | + } | |
171 | + } else | |
172 | + return IMAP_MAILBOX_NONEXISTENT; | |
173 | +} | |
174 | + | |
175 | diff -Naur cyrus-imapd-2.2.12/lib/imapoptions cyrus-imapd-2.2.12-autosieve.uncompiled/lib/imapoptions | |
176 | --- cyrus-imapd-2.2.12/lib/imapoptions 2004-07-21 22:07:45 +0300 | |
177 | +++ cyrus-imapd-2.2.12-autosieve.uncompiled/lib/imapoptions 2005-02-15 13:59:51 +0200 | |
178 | @@ -752,6 +752,15 @@ | |
179 | /* If enabled, lmtpd will look for Sieve scripts in user's home | |
180 | directories: ~user/.sieve. */ | |
181 | ||
182 | +{ "anysievefolder", 0, SWITCH } | |
183 | +/* It must be "yes" in order to permit the autocreation of any INBOX subfolder | |
184 | + requested by a sieve filter, through the "fileinto" action. (default = no) */ | |
185 | + | |
186 | +{ "autosievefolders", NULL, STRING } | |
187 | +/* It is a "|" separated list of subfolders of INBOX that will be automatically created, | |
188 | + if requested by a sieve filter, through the "fileinto" action. (default = null) | |
189 | + i.e. autosievefolders: Junk | Spam */ | |
190 | + | |
191 | { "singleinstancestore", 1, SWITCH } | |
192 | /* If enabled, lmtpd and nntpd attempt to only write one copy of a message per | |
193 | partition and create hard links, resulting in a potentially large |