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

Contents of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.58 - (show annotations)
Mon Jan 26 21:36:36 2004 UTC (20 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.57: +38 -12 lines
File MIME type: text/plain
Daemon mode corrections/improvements.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26