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

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.65 - (show annotations)
Fri Feb 13 12:17:16 2004 UTC (20 years, 1 month ago) by lefcha
Branch: MAIN
Changes since 1.64: +18 -18 lines
File MIME type: text/plain
Stylistic changes.

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 usage(void);
40 void version(void);
41
42
43 /*
44 * IMAPFilter: an IMAP mail filtering utility.
45 */
46 int
47 main(int argc, char *argv[])
48 {
49 int c, r;
50 char *cf; /* Configuration file. */
51 account_t *ca; /* Current account. */
52 mbox_t *cm; /* Current mailbox. */
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 for (ca = accounts; ca != NULL; ca = ca->next) {
160
161 if (setjmp(acctloop))
162 continue;
163
164 if (init_connection(&connpri, ca->server, ca->port,
165 ca->ssl))
166 continue;
167
168 r = response_greeting(&connpri);
169
170 if (opts.debug)
171 test(&connpri);
172
173 if (check_capabilities(&connpri))
174 continue;
175
176 #ifdef SSL_TLS
177 if (ca->ssl == SSL_DISABLED &&
178 connpri.caps & CAPS_STARTTLS)
179 if (negotiate_tls(&connpri) == RESPONSE_OK)
180 check_capabilities(&connpri);
181 #endif
182
183 log_info(LOG_ACCOUNT, ca->key);
184
185 if (r != RESPONSE_PREAUTH) {
186 if (ca->pass_attr == PASS_ATTR_NONE) {
187 printf("Enter password for %s@%s: ",
188 ca->user, ca->server);
189 get_password(ca->pass, PASS_LEN);
190 ca->pass_attr = PASS_ATTR_PLAIN;
191 }
192 #ifdef CRAM_MD5
193 if (connpri.caps & CAPS_CRAMMD5)
194 r = auth_cram_md5(&connpri,
195 ca->user, ca->pass);
196 else
197 #endif
198 r = login(&connpri, ca->user,
199 ca->pass);
200
201 if (r == RESPONSE_NO) {
202 error("username %s or password rejected "
203 "at %s\n", ca->user, ca->server);
204 continue;
205 }
206 }
207 check_namespace(&connpri);
208
209 for (cm = ca->mboxes; cm != NULL; cm = cm->next)
210 if (*cm->filters == NULL)
211 mailbox_status(&connpri, cm->name);
212 else if (!select_mailbox(&connpri, cm->name)) {
213 apply_filters(cm->name, cm->filters);
214 close_mailbox(&connpri);
215 }
216 logout(&connpri);
217
218 close_connection(&connpri);
219 }
220
221 /* Fork if in daemon mode. */
222 if (opts.daemon && !(flags & FLAG_DAEMON)) {
223 switch (fork()) {
224 case -1:
225 fatal(ERROR_FORK, "forking; %s\n",
226 strerror(errno));
227 break;
228 case 0:
229 break;
230 default:
231 log_stop();
232 secmem_clear();
233 debug_stop();
234 exit(0);
235 break;
236 }
237
238 if (setsid() == -1)
239 fatal(ERROR_FORK, "creating session; %s\n",
240 strerror(errno));
241
242 switch (fork()) {
243 case -1:
244 fatal(ERROR_FORK, "forking; %s\n",
245 strerror(errno));
246 break;
247 case 0:
248 break;
249 default:
250 log_stop();
251 secmem_clear();
252 debug_stop();
253 exit(0);
254 break;
255 }
256
257 close(STDIN_FILENO);
258 close(STDOUT_FILENO);
259 close(STDERR_FILENO);
260 if (open("/dev/null", O_RDWR) != -1) {
261 dup(STDIN_FILENO);
262 dup(STDIN_FILENO);
263 }
264 lockfile_create();
265 corefile_disable();
266
267 flags |= FLAG_DAEMON;
268 }
269 if (opts.daemon && flags & FLAG_SIGUSR1) {
270 reread_config(cf);
271 continue;
272 }
273 if (opts.daemon)
274 sleep(opts.daemon);
275 } while (opts.daemon);
276
277 log_stop();
278 secmem_clear();
279
280 lockfile_remove();
281
282 debug_stop();
283
284 exit(0);
285 }
286
287
288 /*
289 * Print a very brief usage message.
290 */
291 void
292 usage(void)
293 {
294 fprintf(stderr,
295 "usage: imapfilter [-DVbk"
296 #ifdef ENCRYPTED_PASSWORDS
297 "p"
298 #endif
299 "qv] [-c configfile] [-d interval] [-l logfile]\n");
300
301 exit(ERROR_UNDEFINED);
302 }
303
304
305 /*
306 * Print program's version, and if it is built in, OpenSSL's version number.
307 */
308 void
309 version(void)
310 {
311 fprintf(stderr, "IMAPFilter %s"
312 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
313 ", OpenSSL 0x%8.8lx"
314 #endif
315 "\n", IMAPFILTER_VERSION
316 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
317 ,SSLeay()
318 #endif
319 );
320
321 exit(ERROR_UNDEFINED);
322 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26