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

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.66 - (show annotations)
Fri Feb 13 12:36:33 2004 UTC (20 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.65: +131 -106 lines
File MIME type: text/plain
Moved some parts of main() to imapfilter() and daemonize() functions.

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 opts. */
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 default:
116 case '?':
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 catch_signals();
134
135 read_config(cf);
136
137 #ifdef ENCRYPTED_PASSWORDS
138 read_passwords();
139
140 if (opts.passwd_editor) {
141 password_editor();
142
143 secmem_clear();
144 lockfile_remove();
145
146 exit(0);
147 }
148 #endif
149
150 log_start();
151
152 buffer_init(&ibuf);
153 buffer_init(&obuf);
154
155 if (opts.daemon)
156 opts.verbosity = -2;
157
158 do {
159 imapfilter();
160
161 if (opts.daemon && !(flags & FLAG_DAEMON))
162 daemonize();
163 if (opts.daemon && flags & FLAG_SIGUSR1) {
164 reread_config(cf);
165 continue;
166 }
167 if (opts.daemon > 0)
168 sleep(opts.daemon);
169 } while (opts.daemon);
170
171 log_stop();
172 secmem_clear();
173
174 lockfile_remove();
175
176 debug_stop();
177
178 exit(0);
179 }
180
181
182 /*
183 * Go through all accounts and apply filters to mailboxes as defined.
184 */
185 void
186 imapfilter(void)
187 {
188 int r;
189 account_t *ca;
190 mbox_t *cm;
191
192 for (ca = accounts; ca != NULL; ca = ca->next) {
193
194 if (setjmp(acctloop))
195 continue;
196
197 if (init_connection(&connpri, ca->server, ca->port,
198 ca->ssl))
199 continue;
200
201 r = response_greeting(&connpri);
202
203 if (opts.debug)
204 test(&connpri);
205
206 if (check_capabilities(&connpri))
207 continue;
208
209 #ifdef SSL_TLS
210 if (ca->ssl == SSL_DISABLED &&
211 connpri.caps & CAPS_STARTTLS)
212 if (negotiate_tls(&connpri) == RESPONSE_OK)
213 check_capabilities(&connpri);
214 #endif
215
216 log_info(LOG_ACCOUNT, ca->key);
217
218 if (r != RESPONSE_PREAUTH) {
219 if (ca->pass_attr == PASS_ATTR_NONE) {
220 printf("Enter password for %s@%s: ",
221 ca->user, ca->server);
222 get_password(ca->pass, PASS_LEN);
223 ca->pass_attr = PASS_ATTR_PLAIN;
224 }
225 #ifdef CRAM_MD5
226 if (connpri.caps & CAPS_CRAMMD5)
227 r = auth_cram_md5(&connpri,
228 ca->user, ca->pass);
229 else
230 #endif
231 r = login(&connpri, ca->user,
232 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",
266 strerror(errno));
267 break;
268 case 0:
269 break;
270 default:
271 log_stop();
272 secmem_clear();
273 debug_stop();
274 exit(0);
275 break;
276 }
277
278 if (setsid() == -1)
279 fatal(ERROR_FORK, "creating session; %s\n",
280 strerror(errno));
281
282 switch (fork()) {
283 case -1:
284 fatal(ERROR_FORK, "forking; %s\n",
285 strerror(errno));
286 break;
287 case 0:
288 break;
289 default:
290 log_stop();
291 secmem_clear();
292 debug_stop();
293 exit(0);
294 break;
295 }
296
297 close(STDIN_FILENO);
298 close(STDOUT_FILENO);
299 close(STDERR_FILENO);
300 if (open("/dev/null", O_RDWR) != -1) {
301 dup(STDIN_FILENO);
302 dup(STDIN_FILENO);
303 }
304 lockfile_create();
305 corefile_disable();
306
307 flags |= FLAG_DAEMON;
308 }
309
310
311 /*
312 * Print a very brief usage message.
313 */
314 void
315 usage(void)
316 {
317
318 fprintf(stderr,
319 "usage: imapfilter [-DVbk"
320 #ifdef ENCRYPTED_PASSWORDS
321 "p"
322 #endif
323 "qv] [-c configfile] [-d interval] [-l logfile]\n");
324
325 exit(ERROR_UNDEFINED);
326 }
327
328
329 /*
330 * Print program's version, and if it is built in, OpenSSL's version number.
331 */
332 void
333 version(void)
334 {
335
336 fprintf(stderr, "IMAPFilter %s"
337 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
338 ", OpenSSL 0x%8.8lx"
339 #endif
340 "\n", IMAPFILTER_VERSION
341 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
342 ,SSLeay()
343 #endif
344 );
345
346 exit(ERROR_UNDEFINED);
347 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26