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

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.67 - (show annotations)
Fri Feb 13 13:03:00 2004 UTC (20 years, 1 month ago) by lefcha
Branch: MAIN
Changes since 1.66: +4 -2 lines
File MIME type: text/plain
Move switch(getopt()) default tag.

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
70 home = getenv("HOME");
71 cf = NULL;
72 connpri.sock = connaux.sock = -1;
73
74 while ((c = getopt(argc, argv, "DVc:d:kl:"
75 #ifdef ENCRYPTED_PASSWORDS
76 "p"
77 #endif
78 "qv")) != -1) {
79 switch (c) {
80 case 'D':
81 if (opts.debug < 2)
82 opts.debug++;
83 break;
84 case 'V':
85 version();
86 /* NOTREACHED */
87 case 'c':
88 cf = optarg;
89 break;
90 case 'd':
91 errno = 0;
92 opts.daemon = strtoul(optarg, NULL, 10);
93 if (errno)
94 opts.daemon = 0;
95 break;
96 case 'k':
97 kill_imapfilter();
98 break;
99 case 'l':
100 strncat(opts.logfile, optarg, PATH_MAX - 1);
101 break;
102 #ifdef ENCRYPTED_PASSWORDS
103 case 'p':
104 opts.passwd_editor = 1;
105 break;
106 #endif
107 case 'q':
108 if (opts.verbosity > -2)
109 opts.verbosity--;
110 break;
111 case 'v':
112 if (opts.verbosity < 2)
113 opts.verbosity++;
114 break;
115 case '?':
116 default:
117 usage();
118 /* NOTREACHED */
119 }
120 }
121
122 debug_start();
123
124 create_homedir();
125
126 lockfile_check();
127 lockfile_create();
128
129 if (!opts.debug)
130 corefile_disable();
131
132 tty_store();
133
134 catch_signals();
135
136 read_config(cf);
137
138 #ifdef ENCRYPTED_PASSWORDS
139 read_passwords();
140
141 if (opts.passwd_editor) {
142 password_editor();
143
144 secmem_clear();
145 lockfile_remove();
146
147 exit(0);
148 }
149 #endif
150
151 log_start();
152
153 buffer_init(&ibuf);
154 buffer_init(&obuf);
155
156 if (opts.daemon)
157 opts.verbosity = -2;
158
159 do {
160 imapfilter();
161
162 if (opts.daemon && !(flags & FLAG_DAEMON))
163 daemonize();
164 if (opts.daemon && flags & FLAG_SIGUSR1) {
165 reread_config(cf);
166 continue;
167 }
168 if (opts.daemon > 0)
169 sleep(opts.daemon);
170 } while (opts.daemon);
171
172 log_stop();
173
174 secmem_clear();
175
176 lockfile_remove();
177
178 debug_stop();
179
180 exit(0);
181 }
182
183
184 /*
185 * Go through all accounts and apply filters to mailboxes as defined.
186 */
187 void
188 imapfilter(void)
189 {
190 int r;
191 account_t *ca;
192 mbox_t *cm;
193
194 for (ca = accounts; ca != NULL; ca = ca->next) {
195
196 if (setjmp(acctloop))
197 continue;
198
199 if (init_connection(&connpri, ca->server, ca->port,
200 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 & CAPS_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 & CAPS_CRAMMD5)
229 r = auth_cram_md5(&connpri,
230 ca->user, ca->pass);
231 else
232 #endif
233 r = login(&connpri, ca->user,
234 ca->pass);
235
236 if (r == RESPONSE_NO) {
237 error("username %s or password rejected "
238 "at %s\n", ca->user, ca->server);
239 continue;
240 }
241 }
242 check_namespace(&connpri);
243
244 for (cm = ca->mboxes; cm != NULL; cm = cm->next)
245 if (*cm->filters == NULL)
246 mailbox_status(&connpri, cm->name);
247 else if (!select_mailbox(&connpri, cm->name)) {
248 apply_filters(cm->name, cm->filters);
249 close_mailbox(&connpri);
250 }
251 logout(&connpri);
252
253 close_connection(&connpri);
254 }
255 }
256
257
258 /*
259 * Fork if in daemon mode.
260 */
261 void
262 daemonize(void)
263 {
264
265 switch (fork()) {
266 case -1:
267 fatal(ERROR_FORK, "forking; %s\n",
268 strerror(errno));
269 break;
270 case 0:
271 break;
272 default:
273 log_stop();
274 secmem_clear();
275 debug_stop();
276 exit(0);
277 break;
278 }
279
280 if (setsid() == -1)
281 fatal(ERROR_FORK, "creating session; %s\n",
282 strerror(errno));
283
284 switch (fork()) {
285 case -1:
286 fatal(ERROR_FORK, "forking; %s\n",
287 strerror(errno));
288 break;
289 case 0:
290 break;
291 default:
292 log_stop();
293 secmem_clear();
294 debug_stop();
295 exit(0);
296 break;
297 }
298
299 close(STDIN_FILENO);
300 close(STDOUT_FILENO);
301 close(STDERR_FILENO);
302 if (open("/dev/null", O_RDWR) != -1) {
303 dup(STDIN_FILENO);
304 dup(STDIN_FILENO);
305 }
306 lockfile_create();
307 corefile_disable();
308
309 flags |= FLAG_DAEMON;
310 }
311
312
313 /*
314 * Print a very brief usage message.
315 */
316 void
317 usage(void)
318 {
319
320 fprintf(stderr,
321 "usage: imapfilter [-DVbk"
322 #ifdef ENCRYPTED_PASSWORDS
323 "p"
324 #endif
325 "qv] [-c configfile] [-d interval] [-l logfile]\n");
326
327 exit(ERROR_UNDEFINED);
328 }
329
330
331 /*
332 * Print program's version, and if it is built in, OpenSSL's version number.
333 */
334 void
335 version(void)
336 {
337
338 fprintf(stderr, "IMAPFilter %s"
339 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
340 ", OpenSSL 0x%8.8lx"
341 #endif
342 "\n", IMAPFILTER_VERSION
343 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
344 ,SSLeay()
345 #endif
346 );
347
348 exit(ERROR_UNDEFINED);
349 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26