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

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.62 - (show annotations)
Mon Feb 9 19:56:42 2004 UTC (20 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.61: +12 -18 lines
File MIME type: text/plain
Add verbosity levels and remove the no warning command line option.

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 unsigned int options; /* Program options. */
30 int verbosity; /* Program verbosity level (-2..2). */
31 unsigned int flags = 0; /* Program flags. */
32 unsigned int interval = 0; /* Poll at the specified interval. */
33 conn_t connpri, connaux; /* Primary and auxiliary IMAP connection. */
34
35 char logfile[PATH_MAX]; /* Log file. */
36 char *home = NULL; /* User's home directory. */
37 char charset[CHARSET_LEN]; /* Charset for IMAP SEARCH requests. */
38
39 jmp_buf acctloop; /* Non-local exit in case of network error. */
40
41
42 void usage(void);
43 void version(void);
44
45
46 /*
47 * IMAPFilter: an IMAP mail filtering utility.
48 */
49 int
50 main(int argc, char *argv[])
51 {
52 int c, r;
53 char *conffile; /* Configuration file. */
54 account_t *ca; /* Current account. */
55 mbox_t *cm; /* Current mailbox. */
56
57 setlocale(LC_ALL, "");
58
59 home = getenv("HOME");
60 options = (OPTION_NAMESPACE | OPTION_PEEK);
61 verbosity = 0;
62 *charset = 0;
63 *logfile = 0;
64 conffile = NULL;
65 connpri.sock = connaux.sock = -1;
66
67 while ((c = getopt(argc, argv, "c:d:Dhkl:"
68 #ifdef ENCRYPTED_PASSWORDS
69 "p"
70 #endif
71 "qvV")) != -1) {
72 switch (c) {
73 case 'c':
74 conffile = optarg;
75 break;
76 case 'd':
77 options |= OPTION_DAEMON_MODE;
78 errno = 0;
79 interval = strtoul(optarg, NULL, 10);
80 if (errno)
81 interval = 0;
82 break;
83 case 'D':
84 options |= OPTION_DEBUG;
85 break;
86 case 'h':
87 usage();
88 exit(ERROR_UNDEFINED);
89 break;
90 case 'k':
91 kill_imapfilter();
92 break;
93 case 'l':
94 strncat(logfile, optarg, PATH_MAX - 1);
95 break;
96 #ifdef ENCRYPTED_PASSWORDS
97 case 'p':
98 options |= OPTION_PASSWORD_EDITOR;
99 break;
100 #endif
101 case 'q':
102 if (verbosity > -2)
103 verbosity--;
104 break;
105 case 'v':
106 if (verbosity < 2)
107 verbosity++;
108 break;
109 case 'V':
110 version();
111 exit(ERROR_UNDEFINED);
112 break;
113 default:
114 usage();
115 exit(ERROR_UNDEFINED);
116 break;
117 }
118 }
119
120 debug_start();
121
122 create_homedir();
123
124 lockfile_check();
125 lockfile_create();
126
127 if (!(options & OPTION_DEBUG))
128 corefile_disable();
129
130 tty_store();
131 catch_signals();
132
133 read_config(conffile);
134
135 #ifdef ENCRYPTED_PASSWORDS
136 read_passwords();
137
138 if ((options & OPTION_PASSWORD_EDITOR)) {
139 password_editor();
140
141 secmem_clear();
142 lockfile_remove();
143
144 exit(0);
145 }
146 #endif
147
148 log_start();
149
150 init_buffer(&ibuf);
151 init_buffer(&obuf);
152
153 if (options & OPTION_DAEMON_MODE)
154 verbosity = -2;
155
156 do {
157 for (ca = accounts; ca != NULL; ca = ca->next) {
158
159 if (setjmp(acctloop))
160 continue;
161
162 if (init_connection(&connpri, ca->server, ca->port,
163 ca->ssl))
164 continue;
165
166 r = greeting_response(&connpri);
167
168 if (options & OPTION_DEBUG)
169 test(&connpri);
170
171 if (check_capabilities(&connpri))
172 continue;
173
174 #ifdef SSL_TLS
175 if (ca->ssl == SSL_DISABLED &&
176 connpri.caps & CAPABILITY_STARTTLS)
177 if (negotiate_tls(&connpri) == RESPONSE_OK)
178 check_capabilities(&connpri);
179 #endif
180
181 log_info(LOG_ACCOUNT, ca->key);
182
183 if (r != RESPONSE_PREAUTH) {
184 if (ca->passwdattr == PASSWORD_NONE) {
185 printf("Enter password for %s@%s: ",
186 ca->username, ca->server);
187 get_password(ca->password, PASSWORD_LEN);
188 ca->passwdattr = PASSWORD_PLAIN;
189 }
190 #ifdef CRAM_MD5
191 if (connpri.caps & CAPABILITY_AUTH_CRAM_MD5)
192 r = auth_cram_md5(&connpri,
193 ca->username, ca->password);
194 else
195 #endif
196 r = login(&connpri, ca->username,
197 ca->password);
198
199 if (r == RESPONSE_NO) {
200 error("username %s or password rejected "
201 "at %s\n", ca->username, ca->server);
202 continue;
203 }
204 }
205 check_namespace(&connpri);
206
207 for (cm = ca->mboxes; cm != NULL; cm = cm->next)
208 if (*cm->filters == NULL)
209 mailbox_status(&connpri, cm->name);
210 else if (!select_mailbox(&connpri, cm->name)) {
211 apply_filters(cm->name, cm->filters);
212 close_mailbox(&connpri);
213 }
214 logout(&connpri);
215
216 close_connection(&connpri);
217 }
218
219 /* Fork if in daemon mode. */
220 if (options & OPTION_DAEMON_MODE &&
221 !(flags & FLAG_DAEMON_MODE)) {
222
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_MODE;
268 }
269 if (options & OPTION_DAEMON_MODE &&
270 flags & FLAG_SIGUSR1_RECEIVED) {
271 reread_config(conffile);
272 continue;
273 }
274 if (interval)
275 sleep(interval);
276 } while (options & OPTION_DAEMON_MODE && interval);
277
278 log_stop();
279 secmem_clear();
280
281 lockfile_remove();
282
283 debug_stop();
284
285 exit(0);
286 }
287
288
289 /*
290 * Print a very brief usage message.
291 */
292 void
293 usage(void)
294 {
295 fprintf(stderr,
296 "usage: imapfilter [-bDhk"
297 #ifdef ENCRYPTED_PASSWORDS
298 "p"
299 #endif
300 "qvV] [-c configfile] [-d interval] [-l logfile]\n");
301 }
302
303
304 /*
305 * Print program's version, and if it is built in, OpenSSL's version number.
306 */
307 void
308 version(void)
309 {
310 fprintf(stderr, "IMAPFilter %s"
311 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
312 ", OpenSSL 0x%8.8lx"
313 #endif
314 "\n", IMAPFILTER_VERSION
315 #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
316 ,SSLeay()
317 #endif
318 );
319 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26