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

Diff of /imapfilter/log.c

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

revision 1.26.2.3 by lefcha, Fri Mar 28 16:57:52 2003 UTC revision 1.46 by lefcha, Sat Feb 14 19:14:43 2004 UTC
# Line 1  Line 1 
1  #include <stdio.h>  #include <stdio.h>
2  #include <stdlib.h>  #include <stdlib.h>
 #include <unistd.h>  
 #include <errno.h>  
3  #include <string.h>  #include <string.h>
4    #include <errno.h>
5  #include <stdarg.h>  #include <stdarg.h>
 #include <signal.h>  
6  #include <limits.h>  #include <limits.h>
7  #include <sys/types.h>  #include <sys/types.h>
8  #include <sys/stat.h>  #include <sys/stat.h>
 #include <fcntl.h>  
9  #include <time.h>  #include <time.h>
10    #include <signal.h>
11    
12  #include "config.h"  #include "config.h"
13  #include "imapfilter.h"  #include "imapfilter.h"
14    #include "pathnames.h"
15    
16    
17  extern int sockpri, sockaux;  extern connection_t connpri, connaux;
18  extern char logfile[PATH_MAX];  extern options_t opts;
19  extern unsigned int options;  extern unsigned int flags;
20    
21    static FILE *debugfp = NULL;    /* Pointer to debug file. */
22  static FILE *logfp = NULL;      /* Pointer to logfile. */  static FILE *logfp = NULL;      /* Pointer to logfile. */
23    
24    
25    void signal_handler(int sig);
26    char *log_time(void);
27    
28    
29  /*  /*
30   * Print message if not in OPTION_DETAILS_QUIET mode.   * Print message if not in the lowest verbosity level.
31   */   */
32  void info(const char *info,...)  void
33    info(const char *info,...)
34  {  {
35      va_list args;          va_list args;
36    
37      if (options & OPTION_DETAILS_QUIET)          if (opts.verbosity == -2)
38          return;                  return;
39    
40      va_start(args, info);          va_start(args, info);
41      vprintf(info, args);          vprintf(info, args);
42      va_end(args);          va_end(args);
43  }  }
44    
45    
46  /*  /*
47   * Print message if in OPTION_DETAILS_VERBOSE mode.   * Print message if in the highest verbosity level.
48   */   */
49  void verbose(const char *info,...)  void
50    verbose(const char *info,...)
51  {  {
52      va_list args;          va_list args;
53    
54      if (options & OPTION_DETAILS_VERBOSE) {          if (opts.verbosity == 2) {
55          va_start(args, info);                  va_start(args, info);
56          vprintf(info, args);                  vprintf(info, args);
57          va_end(args);                  va_end(args);
58      }          }
59    }
60    
61    
62    /*
63     * Write message to debug file.
64     */
65    void
66    debug(const char *debug,...)
67    {
68            va_list args;
69    
70            if (opts.debug && debugfp) {
71                    va_start(args, debug);
72                    vfprintf(debugfp, debug, args);
73                    fflush(debugfp);
74                    va_end(args);
75            }
76  }  }
77    
78    
79  /*  /*
80   * Print error message and write it into logfile.   * Print error message and write it into logfile.
81   */   */
82  void error(const char *errmsg,...)  void
83    error(const char *errmsg,...)
84  {  {
85      va_list args;          va_list args;
86    
87      va_start(args, errmsg);          va_start(args, errmsg);
88    
89      vfprintf(stderr, errmsg, args);          fprintf(stderr, "imapfilter: ");
90            vfprintf(stderr, errmsg, args);
91    
92      if ((options & OPTION_ERRORS) && logfp) {          if (opts.errors && logfp) {
93          vfprintf(logfp, errmsg, args);                  vfprintf(logfp, errmsg, args);
94      }                  fflush(logfp);
95      va_end(args);          }
96            va_end(args);
97  }  }
98    
99    
100  /*  /*
101   * Print error message and exit program.   * Print error message and exit program.
102   */   */
103  void fatal(unsigned int errnum, const char *fatal,...)  void
104    fatal(unsigned int errnum, const char *fatal,...)
105  {  {
106      va_list args;          va_list args;
107    
108      va_start(args, fatal);          va_start(args, fatal);
109      vfprintf(stderr, fatal, args);          fprintf(stderr, "imapfilter: ");
110      va_end(args);          vfprintf(stderr, fatal, args);
111            va_end(args);
112    
113      close_connection(&sockpri);          close_connection(&connpri);
114      close_connection(&sockaux);          close_connection(&connaux);
115      secmem_clear();          secmem_clear();
116      tty_restore();          tty_restore();
117      close_logfile();          log_stop();
118      lockfile_remove();          lockfile_remove();
119            debug_stop();
120    
121      exit(errnum);          exit(errnum);
122  }  }
123    
124    
125  /*  /*
126   * Catch signals that cause program's termination.   * Catch signals that cause rereading of the configuration file or program's
127     * termination.
128   */   */
129  void catch_signals(void)  void
130    catch_signals(void)
131  {  {
132      signal(SIGINT, signal_handler);  
133      signal(SIGQUIT, signal_handler);          signal(SIGUSR1, signal_handler);
134      signal(SIGTERM, signal_handler);          signal(SIGINT, signal_handler);
135            signal(SIGQUIT, signal_handler);
136            signal(SIGTERM, signal_handler);
137  }  }
138    
139    
140  /*  /*
141   * Signal handler for signals that cause termination of program.   * Signal handler for signals that cause rereading of the configuration file or
142     * termination of program.
143   */   */
144  void signal_handler(int sig)  void
145    signal_handler(int sig)
146  {  {
147      fatal(ERROR_SIGNAL, "imapfilter: killed by signal %d\n", sig);  
148            if (sig == SIGUSR1)
149                    flags |= FLAG_SIGUSR1;
150            else
151                    fatal(ERROR_SIGNAL, "killed by signal %d\n", sig);
152  }  }
153    
154    
155  /*  /*
156   * Open the file for saving of logging information.   * Open temporary debug file and associate a stream with the returned file
157     * descriptor.
158   */   */
159  int open_logfile(void)  int
160    debug_start(void)
161  {  {
162      if (!*logfile)          static char dt[] = PATHNAME_DEBUG;
163          return 0;               /* Logging not enabled. */          int fd;
164    
165            if (!opts.debug)
166                    return 0;
167    
168            fd = mkstemp(dt);
169    
170  #ifdef DEBUG          if (fd != -1) {
171      printf("debug: logfile: '%s'\n", logfile);                  debugfp = fdopen(fd, "w");
172  #endif                  if (debugfp == NULL) {
173                            error("opening debug file %s: %s\n", opts.logfile,
174                                strerror(errno));
175                            return ERROR_TRIVIAL;
176                    }
177            }
178            return 0;
179    }
180    
     if (create_file(logfile, S_IRUSR | S_IWUSR))  
         return ERROR_TRIVIAL;  
181    
182      logfp = fopen(logfile, "a");  /*
183     * Close temporary debug file.
184     */
185    int
186    debug_stop(void)
187    {
188    
189      if (!logfp) {          if (debugfp == NULL)
190          error("imapfilter: opening logfile %s: %s\n",                  return 0;
191                logfile, strerror(errno));          else
192          return ERROR_TRIVIAL;                  return fclose(debugfp);
     }  
     return 0;  
193  }  }
194    
195    
196  /*  /*
197   * Close the logfile.   * Open the file for saving of logging information.
198   */   */
199  int close_logfile(void)  int
200    log_start(void)
201  {  {
202      if (!logfp)  
203            if (*opts.logfile == '\0')
204                    return 0;       /* Logging not enabled. */
205    
206            debug("log file: '%s'\n", opts.logfile);
207    
208            if (create_file(opts.logfile, S_IRUSR | S_IWUSR))
209                    return ERROR_TRIVIAL;
210    
211            logfp = fopen(opts.logfile, "a");
212            if (logfp == NULL) {
213                    error("opening log file %s: %s\n", opts.logfile,
214                        strerror(errno));
215                    return ERROR_TRIVIAL;
216            }
217          return 0;          return 0;
     else  
         return fclose(logfp);  
218  }  }
219    
220    
221  /*  /*
222   * Prepares the log entry to be saved through continues calls, and writes it   * Close the log file.
  * to logfile.  
223   */   */
224  void log_info(int flag, void *ptr)  int
225  {  log_stop(void)
226      static struct {  {
227          char *account;  
228          char *mbox;          if (logfp == NULL)
229          char *filter;                  return 0;
         unsigned int *action;  
         char *destaccount;  
         char *destmbox;  
         char *hdrs;  
     } inf = {  
         NULL, NULL, NULL, NULL, NULL, NULL, NULL  
     };  
   
     if (!logfp)  
         return;  
   
     switch (flag) {  
     case LOG_PREAMBLE:  
         fprintf(logfp, "%s %s %s %s %s%s %s\n", get_time(),  
                 inf.account, inf.mbox, inf.filter,  
                 (*inf.action == FILTER_ACTION_DELETE ? "delete" :  
                  *inf.action == FILTER_ACTION_COPY ? "copy" :  
                  *inf.action == FILTER_ACTION_MOVE ? "move" :  
                  *inf.action == FILTER_ACTION_RCOPY ? "rcopy " :  
                  *inf.action == FILTER_ACTION_RMOVE ? "rmove " :  
                  *inf.action == FILTER_ACTION_FLAG_ADD ||  
                  *inf.action == FILTER_ACTION_FLAG_REMOVE ||  
                  *inf.action == FILTER_ACTION_FLAG_REPLACE ? "flag" :  
                  *inf.action == FILTER_ACTION_LIST ? "list" :  
                  "unknown"),  
                 (inf.destaccount == NULL ? "" : inf.destaccount),  
                 (!*inf.destmbox ? "" : inf.destmbox));  
         fflush(logfp);  
         break;  
     case LOG_ACCOUNT:  
         inf.account = (char *)ptr;  
         break;  
     case LOG_MAILBOX:  
         inf.mbox = (char *)ptr;  
         break;  
     case LOG_FILTER:  
         inf.filter = (char *)ptr;  
         break;  
     case LOG_ACTION:  
         inf.action = (unsigned int *)ptr;  
         break;  
     case LOG_DESTINATION_ACCOUNT:  
         if (ptr == NULL)  
             inf.destaccount = NULL;  
230          else          else
231              inf.destaccount = ((account_t *) ptr)->key;                  return fclose(logfp);
         break;  
     case LOG_DESTINATION_MAILBOX:  
         inf.destmbox = (char *)ptr;  
         break;  
     case LOG_HEADER:  
             if (ptr) {  
                 inf.hdrs = (char *)ptr;  
                 fprintf(logfp, "%c", '\t');  
                 while (*inf.hdrs) {  
                     if (*inf.hdrs == '\r') {  
                         fprintf(logfp, "%c", '\n');  
                         if (*(inf.hdrs + 2))  
                             fprintf(logfp, "%c", '\t');  
                         inf.hdrs += 2;  
                     } else  
                         fprintf(logfp, "%c", *(inf.hdrs++));  
                 }  
             }  
         fflush(logfp);  
         break;  
     }  
232  }  }
233    
234    
235    /*
236     * Prepares the log entry to be saved through continues calls, and writes it to
237     * logfile.
238     */
239    void
240    log_info(int flag, void *ptr)
241    {
242            static struct {
243                    char *account;
244                    char *mbox;
245                    char *filter;
246                    unsigned int *action;
247                    char *destaccount;
248                    char *destmbox;
249                    char *hdrs;
250            } inf = {
251                    NULL, NULL, NULL, NULL, NULL, NULL, NULL
252            };
253    
254            if (logfp == NULL)
255                    return;
256    
257            switch (flag) {
258            case LOG_PREAMBLE:
259                    fprintf(logfp, "%s %s %s %s %s%s %s\n", log_time(),
260                        inf.account, inf.mbox, inf.filter,
261                        (*inf.action == ACTION_DELETE ? "delete" :
262                        *inf.action == ACTION_COPY ? "copy" :
263                        *inf.action == ACTION_MOVE ? "move" :
264                        *inf.action == ACTION_RCOPY ? "rcopy " :
265                        *inf.action == ACTION_RMOVE ? "rmove " :
266                        *inf.action == ACTION_FLAG_ADD ||
267                        *inf.action == ACTION_FLAG_REMOVE ||
268                        *inf.action == ACTION_FLAG_REPLACE ? "flag" :
269                        *inf.action == ACTION_LIST ? "list" :
270                        "unknown "),
271                        (inf.destaccount == NULL ? "" : inf.destaccount),
272                        (*inf.destmbox == '\0' ? "" : inf.destmbox));
273                    fflush(logfp);
274                    break;
275            case LOG_ACCOUNT:
276                    inf.account = (char *)ptr;
277                    break;
278            case LOG_MBOX:
279                    inf.mbox = (char *)ptr;
280                    break;
281            case LOG_FILTER:
282                    inf.filter = (char *)ptr;
283                    break;
284            case LOG_ACTION:
285                    inf.action = (unsigned int *)ptr;
286                    break;
287            case LOG_DEST_ACCOUNT:
288                    if (ptr == NULL)
289                            inf.destaccount = NULL;
290                    else
291                            inf.destaccount = ((account_t *) ptr)->key;
292                    break;
293            case LOG_DEST_MBOX:
294                    inf.destmbox = (char *)ptr;
295                    break;
296            case LOG_HEADER:
297                    if (ptr) {
298                            inf.hdrs = (char *)ptr;
299                            fputc('\t', logfp);
300                            while (*inf.hdrs != '\0') {
301                                    if (*inf.hdrs == '\r') {
302                                            fputc('\n', logfp);
303                                            if (*(inf.hdrs + 2) != '\0')
304                                                    fputc('\t', logfp);
305                                            inf.hdrs += 2;
306                                    } else
307                                            fputc(*(inf.hdrs++), logfp);
308                            }
309                    }
310                    fflush(logfp);
311                    break;
312            }
313    }
314    
315    
316  /*  /*
317   * Return current local time and date.   * Return current local time and date.
318   */   */
319  char *get_time(void)  char *
320    log_time(void)
321  {  {
322      char *ct;          char *ct;
323      time_t t;          time_t t;
324    
325      t = time(NULL);          t = time(NULL);
326    
327      ct = ctime(&t);          ct = ctime(&t);
328      *(strchr(ct, '\n')) = 0;          *(strchr(ct, '\n')) = '\0';
329    
330      return ct;          return ct;
331  }  }

Legend:
Removed from v.1.26.2.3  
changed lines
  Added in v.1.46

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26