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

Diff of /imapfilter/file.c

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

revision 1.12 by lefcha, Tue Aug 28 22:43:36 2001 UTC revision 1.13 by lefcha, Mon Sep 10 23:43:29 2001 UTC
# Line 9  Line 9 
9    
10  #include "config.h"  #include "config.h"
11  #include "imapfilter.h"  #include "imapfilter.h"
12  #include "file.h"  #include "data.h"
 #include "log.h"  
13    
14    
15  extern char logfile[PATH_MAX];  extern char logfile[PATH_MAX];
16  extern unsigned int options;  extern unsigned int options;
17    
 account_t *accounts = NULL;     /* All accounts. */  
   
 filter_t *dfilters = NULL;      /* Filters of DENY type. */  
 filter_t *afilters = NULL;      /* Filters of ALLOW type. */  
   
 unsigned int dlimit = 0;  
 unsigned int alimit = 0;        /* DENY and ALLOW message size limits. */  
   
18    
19  /*  /*
20   * Finds path to configuration file, opens it and calls parse_config().   * Find the path to configuration file, open it and call parse_config().
21   */   */
22  int read_config(char *cfg)  int read_config(char *cfg)
23  {  {
# Line 45  int read_config(char *cfg) Line 36  int read_config(char *cfg)
36  #ifdef DEBUG  #ifdef DEBUG
37      printf("debug: configuration file: '%s'\n", cfg);      printf("debug: configuration file: '%s'\n", cfg);
38  #endif  #endif
39  #ifdef PERMISSIONS  #ifdef CHECK_PERMISSIONS
40      check_perms(cfg);      check_permissions(cfg);
41  #endif  #endif
42      fp = fopen(cfg, "r");      fp = fopen(cfg, "r");
43    
# Line 68  int read_config(char *cfg) Line 59  int read_config(char *cfg)
59  }  }
60    
61    
62  #ifdef PERMISSIONS  #ifdef CHECK_PERMISSIONS
63  /*  /*
64   * Checks the permissions of the configuration file.   * Check the permissions of the configuration file.
65   */   */
66  int check_perms(char *cfg)  int check_permissions(char *cfg)
67  {  {
68      struct stat fs;      struct stat fs;
69    
# Line 89  int check_perms(char *cfg) Line 80  int check_perms(char *cfg)
80    
81      if ((fs.st_mode & 00777) != (S_IRUSR | S_IWUSR)) {      if ((fs.st_mode & 00777) != (S_IRUSR | S_IWUSR)) {
82          fprintf(stderr,          fprintf(stderr,
83                  "imapfilter: warning: bad config file %s permissions\n"                  "imapfilter: warning: improper config file %s permissions\n"
84                  "imapfilter: warning: file's mode should be 600 not %o\n",                  "imapfilter: warning: file's mode should be 600 not %o\n",
85                  cfg, fs.st_mode & 00777);                  cfg, fs.st_mode & 00777);
86          return 1;          return 1;
# Line 100  int check_perms(char *cfg) Line 91  int check_perms(char *cfg)
91  #endif  #endif
92    
93  /*  /*
94   * Parses configuration file.   * Parse configuration file.
95   */   */
96  int parse_config(FILE * fp)  int parse_config(FILE * fp)
97  {  {
98      int i;      int i;
99      unsigned int row = 0;      unsigned int row = 0;
100      char line[LINE_MAX];      char line[LINE_MAX];
101      regex_t creg[7];      regex_t creg[10];
102      regmatch_t match[4];      regmatch_t match[7];
103      const char *reg[7] = {      const char *reg[10] = {
104          "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",          "^[[:blank:]]*ACCOUNT[[:blank:]]+([[:graph:]]*):([[:graph:]]*)@([[:alnum:].-]+):?([[:digit:]]{0,5})[[:blank:]]*\n$",
105          "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)\n$",          "^[[:blank:]]*FOLDER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]+([[:graph:]]+)[[:blank:]]*\n$",
106          "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)\n$",          "^[[:blank:]]*FILTER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]*([[:blank:]]OR|[[:blank:]]AND)?[[:blank:]]*\n$",
107          "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*\n$",          "^[[:blank:]]*ACTION[[:blank:]]+(DELETE|COPY|MOVE|LIST)[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",
108          "^[[:blank:]]*(LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",          "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(ALL|ANSWERED|DELETED|DRAFT|FLAGGED|NEW|OLD|RECENT|SEEN|UNANSWERED|UNDELETED|UNDRAFT|UNFLAGGED|UNSEEN)[[:blank:]]*\n$",
109          "^[[:blank:]]*(TEST_MODE|SHOW_HEADERS|UNSEEN_ONLY)[[:blank:]]*=[[:blank:]]*(yes|no)[[:blank:]]*\n$",          "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(BCC|BODY|CC|FROM|SUBJECT|TEXT|TO)[[:blank:]]+([[:print:]]+)\n$",
110            "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(HEADER)[[:blank:]]+([[:graph:]]+)[[:blank:]]+([[:print:]]+)\n$",
111            "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(LARGER|SMALLER)[[:blank:]]+([[:digit:]]+)[[:blank:]]*\n$",
112            "^[[:blank:]]*JOB[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]*\n$",
113          "^([[:blank:]]*\n|#.*\n)$"          "^([[:blank:]]*\n|#.*\n)$"
114      };      };
115    
116      for (i = 0; i < 7; i++)      for (i = 0; i < 10; i++)
117          regcomp(&creg[i], reg[i], REG_EXTENDED);          regcomp(&creg[i], reg[i], REG_EXTENDED);
118    
119      while (fgets(line, LINE_MAX - 1, fp)) {      while (fgets(line, LINE_MAX - 1, fp)) {
120          row++;          row++;
121          if (!regexec(&creg[0], line, 3, match, 0)) {          if (!regexec(&creg[0], line, 6, match, 0)) {
122              if (set_account(line, match))              set_account(line, match);
                 return 1;  
123              continue;              continue;
124          } else if (!regexec(&creg[1], line, 4, match, 0)) {          } else if (!regexec(&creg[1], line, 3, match, 0)) {
125              if (standard_filter(line, match))              set_mboxgrp(line, match);
                 return 1;  
126              continue;              continue;
127          } else if (!regexec(&creg[2], line, 4, match, 0)) {          } else if (!regexec(&creg[2], line, 3, match, 0)) {
128              if (custom_filter(line, match))              set_filter(line, match);
                 return 1;  
129              continue;              continue;
130          } else if (!regexec(&creg[3], line, 3, match, 0)) {          } else if (!regexec(&creg[3], line, 3, match, 0)) {
131              set_limits(line, match);              set_action(line, match);
132              continue;              continue;
133          } else if (!regexec(&creg[4], line, 3, match, 0) ||          } else if (!regexec(&creg[4], line, 7, match, 0) ||
134                     !regexec(&creg[5], line, 3, match, 0)) {                     !regexec(&creg[5], line, 7, match, 0) ||
135              set_options(line, match);                     !regexec(&creg[6], line, 7, match, 0) ||
136                       !regexec(&creg[7], line, 7, match, 0)) {
137                set_mask(line, match);
138              continue;              continue;
139          } else if (!regexec(&creg[6], line, 0, match, 0)) {          } else if (!regexec(&creg[8], line, 3, match, 0)) {
140                set_job(line, match);
141                continue;
142            } else if (!regexec(&creg[9], line, 0, match, 0)) {
143              continue;              continue;
144          } else {          } else {
145              error("imapfilter: parse error in config file at row %d\n",              error("imapfilter: parse error in config file at row %d\n",
# Line 152  int parse_config(FILE * fp) Line 148  int parse_config(FILE * fp)
148          }          }
149      }      }
150    
151      /* Fail if no accounts were defined. */      for (i = 0; i < 10; i++)
     if (!accounts) {  
         fprintf(stderr,  
                 "imapfilter: no accounts defined in config file\n");  
         return 1;  
     }  
   
     /* Fail if no filters were defined. */  
     if (!dfilters && !afilters) {  
         error("imapfilter: no filters defined in config file\n");  
         return 1;  
     }  
   
     for (i = 0; i < 7; i++)  
152          regfree(&creg[i]);          regfree(&creg[i]);
153    
154      return 0;      return 0;
# Line 173  int parse_config(FILE * fp) Line 156  int parse_config(FILE * fp)
156    
157    
158  /*  /*
159   * Allocates memory for accounts, builds linked list, and NULL terminates   * Set other options found in config file.
  * account settings.  
  */  
 account_t *prepare_account(void)  
 {  
     static account_t *ca;       /* Current account. */  
   
     if (!accounts) {  
         accounts = (account_t *) malloc(sizeof(account_t));  
         if (!accounts) {  
             error("imapfilter: allocating memory; %s\n", strerror(errno));  
             return NULL;  
         }  
         ca = accounts;  
     } else {  
         ca->next = (account_t *) malloc(sizeof(account_t));  
         if (!ca->next) {  
             error("imapfilter: allocating memory; %s\n", strerror(errno));  
             return NULL;  
         }  
         ca = ca->next;  
     }  
   
     ca->next = NULL;  
   
     ca->server[0] = 0;  
     ca->port = 143;  
     ca->userid[0] = 0;  
     ca->passwd[0] = 0;  
   
     return ca;  
 }  
   
   
 /*  
  * An account setting was found from parse_config(), changes the  
  * apropriate variable.  
  */  
 int set_account(char *line, regmatch_t * match)  
 {  
     int s;  
     char p[6];  
     static account_t *ca;  
   
     if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {  
         if (!(ca = prepare_account()))  
             return 1;  
         s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);  
         strncpy(ca->server, line + match[2].rm_so, s);  
         ca->server[s] = 0;  
 #ifdef DEBUG  
         printf("debug: account setting SERVER: '%s'\n", ca->server);  
 #endif  
     } else if (accounts) {  
         if (!strncmp(line + match[1].rm_so, "PORT", 4)) {  
             s = min((match[2].rm_eo - match[2].rm_so), sizeof(p));  
             strncpy(p, line + match[2].rm_so, s);  
             p[s] = 0;  
             ca->port = strtoul(p, NULL, 0);  
 #ifdef DEBUG  
             printf("debug: account setting PORT: %d\n", ca->port);  
 #endif  
         } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {  
             s = min((match[2].rm_eo - match[2].rm_so), USERID_MAX - 1);  
             strncpy(ca->userid, line + match[2].rm_so, s);  
             ca->userid[s] = 0;  
 #ifdef DEBUG  
             printf("debug: account setting USERNAME: '%s'\n", ca->userid);  
 #endif  
         } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {  
             s = min((match[2].rm_eo - match[2].rm_so), PASSWD_MAX - 1);  
             strncpy(ca->passwd, line + match[2].rm_so, s);  
             ca->passwd[s] = 0;  
 #ifdef DEBUG  
             printf("debug: account setting PASSWORD: '%s'\n", ca->passwd);  
 #endif  
         }  
     }  
   
     return 0;  
 }  
   
   
 /*  
  * A filter entry was found from parse_config() processes it and saves it.  
  */  
 int set_filters(char *line, regmatch_t * match, int csm)  
 {  
     int s;  
     static filter_t *cdf, *caf;  
     filter_t **cf;  
     filter_t **fl;  
   
     if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {  
 #ifdef DEBUG  
         printf("debug: filter entry DENY:");  
 #endif  
         cf = &cdf;  
         fl = &dfilters;  
     } else {  
 #ifdef DEBUG  
         printf("debug: filter entry ALLOW:");  
 #endif  
         cf = &caf;  
         fl = &afilters;  
     }  
   
     /*  
      * Allocate memory for filter entry and build linked list.  
      */  
   
     if (!(*fl)) {  
         *fl = (filter_t *) malloc(sizeof(filter_t));  
         if (!(*fl)) {  
             error("imapfilter: allocating memory; %s\n", strerror(errno));  
             return 1;  
         }  
         *cf = *fl;  
     } else {  
         (*cf)->next = (filter_t *) malloc(sizeof(filter_t));  
         if (!((*cf)->next)) {  
             error("imapfilter: allocating memory; %s\n", strerror(errno));  
             return 1;  
         }  
         *cf = (*cf)->next;  
     }  
   
     (*cf)->next = NULL;  
   
     (*cf)->custom = csm;  
   
     s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);  
     strncpy((*cf)->name, line + match[2].rm_so, s);  
     (*cf)->name[s] = 0;  
   
     s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);  
     strncpy((*cf)->body, line + match[3].rm_so, s);  
     (*cf)->body[s] = 0;  
   
 #ifdef DEBUG  
     printf(" '%s' '%s'\n", (*cf)->name, (*cf)->body);  
 #endif  
     return 0;  
 }  
   
   
 /*  
  * Sets the DENY and ALLOW limits from the values found in config file.  
  */  
 void set_limits(char *line, regmatch_t * match)  
 {  
     int s;  
     char lim[10];  
   
     s = min((match[2].rm_eo - match[2].rm_so), sizeof(lim));  
     strncpy(lim, line + match[2].rm_so, s);  
     lim[s] = 0;  
   
     if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {  
         dlimit = strtoul(lim, NULL, 0);  
 #ifdef DEBUG  
         printf("debug: size filter DENY_LIMIT: %d\n", dlimit);  
 #endif  
     } else {  
         alimit = strtoul(lim, NULL, 0);  
 #ifdef DEBUG  
         printf("debug: size filter ALLOW_LIMIT: %d\n", alimit);  
 #endif  
     }  
 }  
   
   
 /*  
  * Sets other options found in config file.  
160   */   */
161  void set_options(char *line, regmatch_t * match)  void set_options(char *line, regmatch_t * match)
162  {  {
163      int s;      int s;
164    
165      if (!logfile[0] && !strncmp(line + match[1].rm_so, "LOGFILE", 7)) {      if (!*logfile && !strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
166          s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);          s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
167          strncpy(logfile, line + match[2].rm_so, s);          strncpy(logfile, line + match[2].rm_so, s);
168          logfile[s] = 0;          logfile[s] = 0;
     } else if (!strncmp(line + match[1].rm_so, "TEST_MODE", 9) &&  
                !(options & OPT_TEST_MODE_STICKY)) {  
         if (!strncmp(line + match[2].rm_so, "yes", 3))  
             options |= OPT_TEST_MODE;  
         else if (options & OPT_TEST_MODE)  
             options ^= OPT_TEST_MODE;  
     } else if (!strncmp(line + match[1].rm_so, "SHOW_HEADERS", 12)) {  
         if (!strncmp(line + match[2].rm_so, "yes", 3))  
             options |= OPT_SHOW_HEADERS;  
         else if (options & OPT_UNSEEN_ONLY)  
             options ^= OPT_SHOW_HEADERS;  
     } else if (!strncmp(line + match[1].rm_so, "UNSEEN_ONLY", 11)) {  
         if (!strncmp(line + match[2].rm_so, "yes", 3))  
             options |= OPT_UNSEEN_ONLY;  
         else if (options & OPT_UNSEEN_ONLY)  
             options ^= OPT_UNSEEN_ONLY;  
169      }      }
170  }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26