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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide annotations)
Mon Aug 20 21:40:57 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.3: +53 -13 lines
File MIME type: text/plain
Added message size limits support

1 lefcha 1.1 #include <stdio.h>
2     #include <errno.h>
3     #include <regex.h>
4     #include <string.h>
5     #include <stdlib.h>
6     #include <limits.h>
7    
8     #include "config.h"
9     #include "imapfilter.h"
10     #include "file.h"
11     #include "log.h"
12    
13    
14     account_data account;
15 lefcha 1.2 filter_entry **dfilters; /* Filters of DENY type. */
16     filter_entry **afilters; /* Filters of ALLOW type. */
17     int dfcnt = 0;
18     int afcnt = 0; /* DENY and ALLOW type filters found
19 lefcha 1.4 in the configuration file. */
20     unsigned int dlimit = 0;
21     unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
22 lefcha 1.1
23    
24     /*
25     * Finds path to configuration file, opens it and calls parse_config().
26     */
27     int read_config(char *cfg)
28     {
29     int r;
30     FILE *fp;
31     char *home = NULL;
32    
33     if (!cfg) {
34     cfg = (char *) malloc(PATH_MAX * sizeof(char));
35    
36     home = getenv("HOME");
37    
38     snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");
39     }
40     #ifdef DEBUG
41     printf("debug: configuration file: %s\n", cfg);
42     #endif
43    
44     fp = fopen(cfg, "r");
45    
46     if (!fp) {
47     fprintf(stderr, "imapfilter: Could not open config file %s; %s\n",
48     cfg, strerror(errno));
49     return FAILURE;
50     }
51    
52     r = parse_config(fp);
53    
54     fclose(fp);
55    
56     return r;
57     }
58    
59     /*
60     * Parses configuration file.
61     */
62     int parse_config(FILE * fp)
63     {
64     int i;
65     unsigned int row = 0;
66     char line[LINE_MAX];
67 lefcha 1.4 regex_t comreg[5];
68 lefcha 1.2 regmatch_t match[4];
69 lefcha 1.4 const char *reg[5] = {
70 lefcha 1.1 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
71 lefcha 1.2 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
72     "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
73 lefcha 1.4 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
74 lefcha 1.1 "^[[:blank:]]*#{0,1}.*"
75     };
76    
77 lefcha 1.4 for (i = 0; i < 5; i++)
78 lefcha 1.1 regcomp(&comreg[i], reg[i], REG_EXTENDED);
79    
80     while (fgets(line, LINE_MAX - 1, fp)) {
81     row++;
82     if (!regexec(&comreg[0], line, 3, match, 0)) {
83     set_account(line, match);
84     continue;
85 lefcha 1.2 } else if (!regexec(&comreg[1], line, 4, match, 0)) {
86 lefcha 1.1 standard_filter(line, match);
87     continue;
88 lefcha 1.2 } else if (!regexec(&comreg[2], line, 4, match, 0)) {
89     custom_filter(line, match);
90 lefcha 1.1 continue;
91 lefcha 1.4 } else if (!regexec(&comreg[3], line, 3, match, 0)) {
92     set_limits(line, match);
93     continue;
94     } else if (!regexec(&comreg[4], line, 1, match, 0))
95 lefcha 1.1 continue;
96     else {
97     fprintf(stderr,
98     "imapfilter: parse error in config file at row %d\n",
99     row);
100     return FAILURE;
101     }
102     }
103 lefcha 1.3
104 lefcha 1.4 /* Fail if no filters were defined. */
105 lefcha 1.3 if (!dfcnt && !afcnt) {
106     fprintf(stderr, "imapfilter: no filters defined in config file\n");
107     return FAILURE;
108     }
109 lefcha 1.1 #ifdef DEBUG
110     printf("debug: account setting SERVER: '%s'\n"
111     "debug: account setting PORT: %d\n"
112     "debug: account setting USERNAME: '%s'\n"
113     "debug: account setting PASSWORD: '%s'\n"
114 lefcha 1.4 "debug: account setting LOGFILE: '%s'\n"
115     "debug: setting DENY_LIMIT: %d\n"
116     "debug: setting ALLOW_LIMIT: %d\n",
117 lefcha 1.1 account.server, account.port, account.username,
118 lefcha 1.4 account.password, account.logfile, dlimit, alimit);
119 lefcha 1.1 #endif
120     return SUCCESS;
121     }
122    
123    
124     /*
125 lefcha 1.4 * NULL terminate account settings.
126     */
127     void prepare_account(void)
128     {
129     account.server[0] = 0;
130     account.port = 143;
131     account.username[0] = 0;
132     account.password[0] = 0;
133     account.logfile[0] = 0;
134     }
135    
136    
137     /*
138 lefcha 1.1 * An account setting was found from parse_config(), changes the
139     * apropriate variable.
140     */
141     void set_account(char *line, regmatch_t * match)
142     {
143     int s;
144     char port[6];
145    
146     if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
147     s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
148     strncpy(account.server, line + match[2].rm_so, s);
149     account.server[s] = 0;
150     } else if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
151 lefcha 1.4 s = min((match[2].rm_eo - match[2].rm_so), sizeof(port));
152     strncpy(port, line + match[2].rm_so, s);
153     port[s] = 0;
154 lefcha 1.1 account.port = strtoul(port, NULL, 0);
155     } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
156     s = min((match[2].rm_eo - match[2].rm_so), USERNAME_MAX - 1);
157     strncpy(account.username, line + match[2].rm_so, s);
158     account.username[s] = 0;
159     } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
160     s = min((match[2].rm_eo - match[2].rm_so), PASSWORD_MAX - 1);
161     strncpy(account.password, line + match[2].rm_so, s);
162     account.password[s] = 0;
163     } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
164     s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
165     strncpy(account.logfile, line + match[2].rm_so, s);
166     account.logfile[s] = 0;
167     }
168     }
169    
170    
171     /*
172 lefcha 1.4 * A filter entry was found from parse_config() processes it and saves it.
173 lefcha 1.1 */
174     void set_filters(char *line, regmatch_t * match, int expl)
175     {
176     int s;
177 lefcha 1.2 int *fcnt;
178     filter_entry ***filters;
179    
180     if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
181     #ifdef DEBUG
182     printf("debug: filter entry: DENY");
183     #endif
184     fcnt = &dfcnt;
185     filters = &dfilters;
186     } else {
187     #ifdef DEBUG
188     printf("debug: filter entry: ALLOW");
189     #endif
190     fcnt = &afcnt;
191     filters = &afilters;
192     }
193 lefcha 1.1
194     /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */
195 lefcha 1.2 if (!*fcnt)
196     *filters =
197 lefcha 1.1 (filter_entry **) malloc(FILTER_ENTRIES_MAX *
198 lefcha 1.2 sizeof(filter_entry *));
199     else if (!(*fcnt % FILTER_ENTRIES_MAX))
200     *filters = (filter_entry **) realloc(*filters,
201     (((*fcnt /
202     FILTER_ENTRIES_MAX) +
203     1) * FILTER_ENTRIES_MAX) *
204     sizeof(filter_entry *));
205    
206     (*filters)[*fcnt] = (filter_entry *) malloc(sizeof(filter_entry));
207    
208     (*filters)[*fcnt]->custom = expl;
209    
210     s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
211     strncpy((*filters)[*fcnt]->name, line + match[2].rm_so, s);
212     (*filters)[*fcnt]->name[s] = 0;
213    
214     s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
215     strncpy((*filters)[*fcnt]->body, line + match[3].rm_so, s);
216     (*filters)[*fcnt]->body[s] = 0;
217 lefcha 1.1
218     #ifdef DEBUG
219 lefcha 1.2 printf(" '%s': '%s'\n", (*filters)[*fcnt]->name,
220     (*filters)[*fcnt]->body);
221 lefcha 1.1 #endif
222    
223 lefcha 1.2 (*fcnt)++;
224 lefcha 1.4 }
225    
226    
227     /*
228     * Sets the DENY and ALLOW limits from the values found in config file.
229     */
230     void set_limits(char *line, regmatch_t * match)
231     {
232     int s;
233     char limit[10];
234    
235     s = min((match[2].rm_eo - match[2].rm_so), sizeof(limit));
236     strncpy(limit, line + match[2].rm_so, s);
237     limit[s] = 0;
238    
239     if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
240     dlimit = strtoul(limit, NULL, 0);
241     } else {
242     alimit = strtoul(limit, NULL, 0);
243     }
244 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26