/[imapfilter]/imapfilter/imapfilter.c
ViewVC logotype

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.70 - (show annotations)
Sat Feb 14 23:09:20 2004 UTC (20 years, 1 month ago) by lefcha
Branch: MAIN
CVS Tags: HEAD
Changes since 1.69: +1 -0 lines
File MIME type: text/plain
Initialize force_protocol variable.

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <limits.h>
8 #include <fcntl.h>
9 #include <setjmp.h>
10 #include <locale.h>
11
12 #include "config.h"
13 #include "imapfilter.h"
14 #include "version.h"
15 #include "account.h"
16 #include "filter.h"
17 #include "buffer.h"
18
19 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
20 #include <openssl/opensslv.h>
21 #include <openssl/crypto.h>
22 #endif
23
24
25 extern account_t *accounts;
26 extern filter_t *filters;
27 extern buffer_t ibuf, obuf;
28
29 options_t opts; /* Program options. */
30 unsigned int flags = 0; /* Program flags. */
31
32 connection_t connpri, connaux; /* Primary and auxiliary IMAP connection. */
33
34 char *home = NULL; /* User's home directory. */
35
36 jmp_buf acctloop; /* Non-local exit in case of network error. */
37
38
39 void imapfilter(void);
40 void daemonize(void);
41 void usage(void);
42 void version(void);
43
44
45 /*
46 * IMAPFilter: an IMAP mail filtering utility.
47 */
48 int
49 main(int argc, char *argv[])
50 {
51 int c;
52 char *cf;
53
54 setlocale(LC_ALL, "");
55
56 opts.debug = 0;
57 opts.verbosity = 0;
58 opts.timeout = -1;
59 opts.daemon = 0;
60 opts.headers = 0;
61 opts.errors = 0;
62 opts.namespace = 1;
63 opts.expunge = 0;
64 opts.subscribe = 0;
65 opts.peek = 1;
66 opts.passwd_editor = 0;
67 opts.charset[0] = '\0';
68 opts.logfile[0] = '\0';
69 opts.force_protocol = PROTOCOL_NONE;
70
71 home = getenv("HOME");
72 cf = NULL;
73 connpri.sock = connaux.sock = -1;
74
75 while ((c = getopt(argc, argv, "DVc:d:kl:"
76 #ifdef ENCRYPTED_PASSWORDS
77 "p"
78 #endif
79 "qv")) != -1) {
80 switch (c) {
81 case 'D':
82 if (opts.debug < 2)
83 opts.debug++;
84 break;
85 case 'V':
86 version();
87 /* NOTREACHED */
88 case 'c':
89 cf = optarg;
90 break;
91 case 'd':
92 errno = 0;
93 opts.daemon = strtoul(optarg, NULL, 10);
94 if (errno)
95 opts.daemon = 0;
96 break;
97 case 'k':
98 kill_imapfilter();
99 break;
100 case 'l':
101 strncat(opts.logfile, optarg, PATH_MAX - 1);
102 break;
103 #ifdef ENCRYPTED_PASSWORDS
104 case 'p':
105 opts.passwd_editor = 1;
106 break;
107 #endif
108 case 'q':
109 if (opts.verbosity > -2)
110 opts.verbosity--;
111 break;
112 case 'v':
113 if (opts.verbosity < 2)
114 opts.verbosity++;
115 break;
116 case '?':
117 default:
118 usage();
119 /* NOTREACHED */
120 }
121 }
122
123 debug_start();
124
125 create_homedir();
126
127 lockfile_check();
128 lockfile_create();
129
130 if (!opts.debug)
131 corefile_disable();
132
133 tty_store();
134
135 catch_signals();
136
137 read_config(cf);
138
139 #ifdef ENCRYPTED_PASSWORDS
140 read_passwords();
141
142 if (opts.passwd_editor) {
143 password_editor();
144
145 secmem_clear();
146 lockfile_remove();
147
148 exit(0);
149 }
150 #endif
151
152 log_start();
153
154 buffer_init(&ibuf);
155 buffer_init(&obuf);
156
157 if (opts.daemon)
158 opts.verbosity = -2;
159
160 do {
161 imapfilter();
162
163 if (opts.daemon && !(flags & FLAG_DAEMON))
164 daemonize();
165 if (opts.daemon && flags & FLAG_SIGUSR1) {
166 reread_config(cf);
167 continue;
168 }
169 if (opts.daemon > 0)
170 sleep(opts.daemon);
171 } while (opts.daemon);
172
173 log_stop();
174
175 secmem_clear();
176
177 lockfile_remove();
178
179 debug_stop();
180
181 exit(0);
182 }
183
184
185 /*
186 * Go through all accounts and apply filters to mailboxes as defined.
187 */
188 void
189 imapfilter(void)
190 {
191 int r;
192 account_t *ca;
193 mbox_t *cm;
194
195 for (ca = accounts; ca != NULL; ca = ca->next) {
196
197 if (setjmp(acctloop))
198 continue;
199
200 if (init_connection(&connpri, ca->server, ca->port, ca->ssl))
201 continue;
202
203 r = response_greeting(&connpri);
204
205 if (opts.debug)
206 test(&connpri);
207
208 if (check_capabilities(&connpri))
209 continue;
210
211 #ifdef SSL_TLS
212 if (ca->ssl == SSL_DISABLED &&
213 connpri.caps & CAPABILITY_STARTTLS)
214 if (negotiate_tls(&connpri) == RESPONSE_OK)
215 check_capabilities(&connpri);
216 #endif
217
218 log_info(LOG_ACCOUNT, ca->key);
219
220 if (r != RESPONSE_PREAUTH) {
221 if (ca->pass_attr == PASS_ATTR_NONE) {
222 printf("Enter password for %s@%s: ",
223 ca->user, ca->server);
224 get_password(ca->pass, PASS_LEN);
225 ca->pass_attr = PASS_ATTR_PLAIN;
226 }
227 #ifdef CRAM_MD5
228 if (connpri.caps & CAPABILITY_CRAMMD5)
229 r = auth_cram_md5(&connpri, ca->user, ca->pass);
230 else
231 #endif
232 r = login(&connpri, ca->user, ca->pass);
233
234 if (r == RESPONSE_NO) {
235 error("username %s or password rejected "
236 "at %s\n", ca->user, ca->server);
237 continue;
238 }
239 }
240 check_namespace(&connpri);
241
242 for (cm = ca->mboxes; cm != NULL; cm = cm->next)
243 if (*cm->filters == NULL)
244 mailbox_status(&connpri, cm->name);
245 else if (!select_mailbox(&connpri, cm->name)) {
246 apply_filters(cm->name, cm->filters);
247 close_mailbox(&connpri);
248 }
249 logout(&connpri);
250
251 close_connection(&connpri);
252 }
253 }
254
255
256 /*
257 * Fork if in daemon mode.
258 */
259 void
260 daemonize(void)
261 {
262
263 switch (fork()) {
264 case -1:
265 fatal(ERROR_FORK, "forking; %s\n", strerror(errno));
266 break;
267 case 0:
268 break;
269 default:
270 log_stop();
271 secmem_clear();
272 debug_stop();
273 exit(0);
274 break;
275 }
276
277 if (setsid() == -1)
278 fatal(ERROR_FORK, "creating session; %s\n", strerror(errno));
279
280 switch (fork()) {
281 case -1:
282 fatal(ERROR_FORK, "forking; %s\n", strerror(errno));
283 break;
284 case 0:
285 break;
286 default:
287 log_stop();
288 secmem_clear();
289 debug_stop();
290 exit(0);
291 break;
292 }
293
294 close(STDIN_FILENO);
295 close(STDOUT_FILENO);
296 close(STDERR_FILENO);
297 if (open("/dev/null", O_RDWR) != -1) {
298 dup(STDIN_FILENO);
299 dup(STDIN_FILENO);
300 }
301 lockfile_create();
302 corefile_disable();
303
304 flags |= FLAG_DAEMON;
305 }
306
307
308 /*
309 * Print a very brief usage message.
310 */
311 void
312 usage(void)
313 {
314
315 fprintf(stderr,
316 "usage: imapfilter [-DVbk"
317 #ifdef ENCRYPTED_PASSWORDS
318 "p"
319 #endif
320 "qv] [-c configfile] [-d interval] [-l logfile]\n");
321
322 exit(ERROR_UNDEFINED);
323 }
324
325
326 /*
327 * Print program's version, and if it is built in, OpenSSL's version number.
328 */
329 void
330 version(void)
331 {
332
333 fprintf(stderr, "IMAPFilter %s"
334 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
335 ", OpenSSL 0x%8.8lx"
336 #endif
337 "\n", IMAPFILTER_VERSION
338 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
339 ,SSLeay()
340 #endif
341 );
342
343 exit(ERROR_UNDEFINED);
344 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26