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

Diff of /imapfilter/imapfilter.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by lefcha, Sat Aug 11 15:52:52 2001 UTC revision 1.70 by lefcha, Sat Feb 14 23:09:20 2004 UTC
# Line 1  Line 1 
1  #include <stdio.h>  #include <stdio.h>
2    #include <stdlib.h>
3    #include <sys/types.h>
4  #include <unistd.h>  #include <unistd.h>
5  #include <string.h>  #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"  #include "config.h"
13  #include "imapfilter.h"  #include "imapfilter.h"
14  #include "file.h"  #include "version.h"
15  #include "connect.h"  #include "account.h"
16  #include "imap.h"  #include "filter.h"
17  #include "log.h"  #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  int options;                    /* Program options. */  jmp_buf acctloop;               /* Non-local exit in case of network error. */
 extern int sock;  
 extern account_data account;  
37    
38    
39    void imapfilter(void);
40    void daemonize(void);
41    void usage(void);
42    void version(void);
43    
44  int main(int argc, char **argv)  
45    /*
46     * IMAPFilter: an IMAP mail filtering utility.
47     */
48    int
49    main(int argc, char *argv[])
50  {  {
51      char *config = NULL;        /* Configuration file. */          int c;
52      int c;          char *cf;
53    
54      options = OPTION_DETAILS_NORMAL;          setlocale(LC_ALL, "");
     account.logfile[0] = 0;  
55    
56      while ((c = getopt(argc, argv, "l:qtvc:L")) != -1) {          opts.debug = 0;
57          switch (c) {          opts.verbosity = 0;
58          case 'l':          opts.timeout = -1;
59              strncpy(account.logfile, optarg, FILENAME_MAX);          opts.daemon = 0;
60              break;          opts.headers = 0;
61          case 'q':          opts.errors = 0;
62              options &= OPTION_DETAILS_CLEAR;          opts.namespace = 1;
63              options |= OPTION_DETAILS_QUITE;          opts.expunge = 0;
64              break;          opts.subscribe = 0;
65          case 't':          opts.peek = 1;
66              options |= OPTION_TEST_MODE;          opts.passwd_editor = 0;
67              break;          opts.charset[0] = '\0';
68          case 'v':          opts.logfile[0] = '\0';
69              options &= OPTION_DETAILS_CLEAR;          opts.force_protocol = PROTOCOL_NONE;
70              options |= OPTION_DETAILS_VERBOSE;  
71              break;          home = getenv("HOME");
72          case 'c':          cf = NULL;
73              config = optarg;          connpri.sock = connaux.sock = -1;
74              break;  
75          case 'L':          while ((c = getopt(argc, argv, "DVc:d:kl:"
76              options |= OPTION_LOGGING_DISABLED;  #ifdef ENCRYPTED_PASSWORDS
77              break;              "p"
78          default:  #endif
79              fprintf(stderr,              "qv")) != -1) {
80                      "usage: imapfilter [-hqtvL] [-c configfile] [-l logfile]\n");                  switch (c) {
81              exit(1);                  case 'D':
82              break;                          if (opts.debug < 2)
83                                    opts.debug++;
84                            break;
85                    case 'V':
86                            version();
87                            /* NOTREACHED */
88                    case 'c':
89                            cf = optarg;
90                            break;
91                    case 'd':
92                            errno = 0;
93                            opts.daemon = strtoul(optarg, NULL, 10);
94                            if (errno)
95                                    opts.daemon = 0;
96                            break;
97                    case 'k':
98                            kill_imapfilter();
99                            break;
100                    case 'l':
101                            strncat(opts.logfile, optarg, PATH_MAX - 1);
102                            break;
103    #ifdef ENCRYPTED_PASSWORDS
104                    case 'p':
105                            opts.passwd_editor = 1;
106                            break;
107    #endif
108                    case 'q':
109                            if (opts.verbosity > -2)
110                                    opts.verbosity--;
111                            break;
112                    case 'v':
113                            if (opts.verbosity < 2)
114                                    opts.verbosity++;
115                            break;
116                    case '?':
117                    default:
118                            usage();
119                            /* NOTREACHED */
120                    }
121          }          }
     }  
122    
123      if (read_config(config) || open_logfile())          debug_start();
124          exit(1);  
125            create_homedir();
126    
127            lockfile_check();
128            lockfile_create();
129    
130            if (!opts.debug)
131                    corefile_disable();
132    
133            tty_store();
134    
135            catch_signals();
136    
137            read_config(cf);
138    
139    #ifdef ENCRYPTED_PASSWORDS
140            read_passwords();
141    
142            if (opts.passwd_editor) {
143                    password_editor();
144    
145                    secmem_clear();
146                    lockfile_remove();
147    
148                    exit(0);
149            }
150    #endif
151    
152            log_start();
153    
154            buffer_init(&ibuf);
155            buffer_init(&obuf);
156    
157            if (opts.daemon)
158                    opts.verbosity = -2;
159    
160            do {
161                    imapfilter();
162    
163                    if (opts.daemon && !(flags & FLAG_DAEMON))
164                            daemonize();
165                    if (opts.daemon && flags & FLAG_SIGUSR1) {
166                            reread_config(cf);
167                            continue;
168                    }
169                    if (opts.daemon > 0)
170                            sleep(opts.daemon);
171            } while (opts.daemon);
172    
173            log_stop();
174    
175            secmem_clear();
176    
177            lockfile_remove();
178    
179            debug_stop();
180    
181            exit(0);
182    }
183    
184    
185      if (establish_connection()) {  /*
186          close_logfile();   * Go through all accounts and apply filters to mailboxes as defined.
187          exit(2);   */
188      }  void
189    imapfilter(void)
190    {
191            int r;
192            account_t *ca;
193            mbox_t *cm;
194    
195            for (ca = accounts; ca != NULL; ca = ca->next) {
196    
197                    if (setjmp(acctloop))
198                            continue;
199    
200                    if (init_connection(&connpri, ca->server, ca->port, 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      clear_stream();  #ifdef SSL_TLS
212                    if (ca->ssl == SSL_DISABLED &&
213                        connpri.caps & CAPABILITY_STARTTLS)
214                            if (negotiate_tls(&connpri) == RESPONSE_OK)
215                                    check_capabilities(&connpri);
216    #endif
217    
218                    log_info(LOG_ACCOUNT, ca->key);
219    
220  #ifdef DEBUG                  if (r != RESPONSE_PREAUTH) {
221      imap_noop();                          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 & CAPABILITY_CRAMMD5)
229                                    r = auth_cram_md5(&connpri, ca->user, ca->pass);
230                            else
231  #endif  #endif
232                                    r = login(&connpri, ca->user, ca->pass);
233    
234      imap_login();                          if (r == RESPONSE_NO) {
235      imap_select();                                  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      apply_filters();                  close_connection(&connpri);
252            }
253    }
254    
     imap_logout();  
255    
256      close_connection();  /*
257     * Fork if in daemon mode.
258     */
259    void
260    daemonize(void)
261    {
262    
263      close_logfile();          switch (fork()) {
264                    case -1:
265                    fatal(ERROR_FORK, "forking; %s\n", strerror(errno));
266                    break;
267            case 0:
268                    break;
269            default:
270                    log_stop();
271                    secmem_clear();
272                    debug_stop();
273                    exit(0);
274                    break;
275            }
276    
277      exit(0);          if (setsid() == -1)
278                    fatal(ERROR_FORK, "creating session; %s\n", strerror(errno));
279    
280            switch (fork()) {
281            case -1:
282                    fatal(ERROR_FORK, "forking; %s\n", strerror(errno));
283                    break;
284            case 0:
285                    break;
286            default:
287                    log_stop();
288                    secmem_clear();
289                    debug_stop();
290                    exit(0);
291                    break;
292            }
293    
294            close(STDIN_FILENO);
295            close(STDOUT_FILENO);
296            close(STDERR_FILENO);
297            if (open("/dev/null", O_RDWR) != -1) {
298                    dup(STDIN_FILENO);
299                    dup(STDIN_FILENO);
300            }
301            lockfile_create();
302            corefile_disable();
303    
304            flags |= FLAG_DAEMON;
305  }  }
306    
307    
308  /*  /*
309   * Search and if found (and not in test mode) delete any messages   * Print a very brief usage message.
  * that match the defined filters.  
310   */   */
311  void apply_filters(void)  void
312    usage(void)
313  {  {
     char results[SEARCH_RESULTS_MAX];  
314    
315      imap_search();          fprintf(stderr,
316                "usage: imapfilter [-DVbk"
317    #ifdef ENCRYPTED_PASSWORDS
318                "p"
319    #endif
320                "qv] [-c configfile] [-d interval] [-l logfile]\n");
321    
322            exit(ERROR_UNDEFINED);
323    }
324    
325    
326    /*
327     * Print program's version, and if it is built in, OpenSSL's version number.
328     */
329    void
330    version(void)
331    {
332    
333            fprintf(stderr, "IMAPFilter %s"
334    #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
335                ", OpenSSL 0x%8.8lx"
336    #endif
337                "\n", IMAPFILTER_VERSION
338    #if defined SSL_TLS || defined ENCRYPTED_PASSWORDS || defined CRAM_MD5
339                ,SSLeay()
340    #endif
341            );
342    
343      if (!search_response(results)) {          exit(ERROR_UNDEFINED);
         delete_messages(results);  
         if (!(options & OPTION_TEST_MODE))  
             imap_expunge();  
     }  
344  }  }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.70

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26