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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (hide annotations)
Sun Aug 26 10:02:46 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.8: +30 -7 lines
File MIME type: text/plain
Some checks while allocating mem

1 lefcha 1.1 #include <stdio.h>
2     #include <errno.h>
3 lefcha 1.5 #include <sys/types.h>
4 lefcha 1.1 #include <regex.h>
5     #include <string.h>
6     #include <stdlib.h>
7     #include <limits.h>
8    
9     #include "config.h"
10     #include "imapfilter.h"
11     #include "file.h"
12     #include "log.h"
13    
14    
15 lefcha 1.6 extern char logfile[PATH_MAX];
16 lefcha 1.8
17     account_t *accounts = NULL; /* All accounts. */
18    
19     filter_t *dfilters; /* Filters of DENY type. */
20     filter_t *afilters; /* Filters of ALLOW type. */
21    
22 lefcha 1.4 unsigned int dlimit = 0;
23     unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
24 lefcha 1.1
25    
26     /*
27     * Finds path to configuration file, opens it and calls parse_config().
28     */
29     int read_config(char *cfg)
30     {
31     int r;
32     FILE *fp;
33     char *home = NULL;
34    
35     if (!cfg) {
36     cfg = (char *) malloc(PATH_MAX * sizeof(char));
37    
38 lefcha 1.8
39 lefcha 1.1 home = getenv("HOME");
40    
41     snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");
42     }
43     #ifdef DEBUG
44     printf("debug: configuration file: %s\n", cfg);
45     #endif
46    
47     fp = fopen(cfg, "r");
48    
49     if (!fp) {
50 lefcha 1.7 fprintf(stderr, "imapfilter: opening config file %s; %s\n",
51 lefcha 1.1 cfg, strerror(errno));
52 lefcha 1.8 return 1;
53 lefcha 1.1 }
54    
55     r = parse_config(fp);
56    
57     fclose(fp);
58    
59     return r;
60     }
61    
62 lefcha 1.6
63 lefcha 1.1 /*
64     * Parses configuration file.
65     */
66     int parse_config(FILE * fp)
67     {
68     int i;
69     unsigned int row = 0;
70     char line[LINE_MAX];
71 lefcha 1.8 regex_t creg[5];
72 lefcha 1.2 regmatch_t match[4];
73 lefcha 1.4 const char *reg[5] = {
74 lefcha 1.1 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
75 lefcha 1.2 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
76     "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
77 lefcha 1.4 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
78 lefcha 1.1 "^[[:blank:]]*#{0,1}.*"
79     };
80    
81 lefcha 1.4 for (i = 0; i < 5; i++)
82 lefcha 1.8 regcomp(&creg[i], reg[i], REG_EXTENDED);
83 lefcha 1.1
84     while (fgets(line, LINE_MAX - 1, fp)) {
85     row++;
86 lefcha 1.8 if (!regexec(&creg[0], line, 3, match, 0)) {
87 lefcha 1.9 if (set_account(line, match))
88     return 1;
89 lefcha 1.1 continue;
90 lefcha 1.8 } else if (!regexec(&creg[1], line, 4, match, 0)) {
91 lefcha 1.9 if (standard_filter(line, match))
92     return 1;
93 lefcha 1.1 continue;
94 lefcha 1.8 } else if (!regexec(&creg[2], line, 4, match, 0)) {
95 lefcha 1.9 if (custom_filter(line, match))
96     return 1;
97 lefcha 1.1 continue;
98 lefcha 1.8 } else if (!regexec(&creg[3], line, 3, match, 0)) {
99 lefcha 1.4 set_limits(line, match);
100     continue;
101 lefcha 1.8 } else if (!regexec(&creg[4], line, 1, match, 0))
102 lefcha 1.1 continue;
103     else {
104     fprintf(stderr,
105     "imapfilter: parse error in config file at row %d\n",
106     row);
107 lefcha 1.8 return 1;
108 lefcha 1.1 }
109     }
110 lefcha 1.3
111 lefcha 1.6 /* Fail if no accounts were defined. */
112 lefcha 1.8 if (!accounts) {
113 lefcha 1.6 fprintf(stderr,
114     "imapfilter: no accounts defined in config file\n");
115 lefcha 1.8 return 1;
116 lefcha 1.6 }
117    
118 lefcha 1.8 /* Fail if no filters were defined. */
119     if (!dfilters && !afilters) {
120 lefcha 1.3 fprintf(stderr, "imapfilter: no filters defined in config file\n");
121 lefcha 1.8 return 1;
122 lefcha 1.3 }
123 lefcha 1.6
124 lefcha 1.8 return 0;
125 lefcha 1.1 }
126    
127    
128     /*
129 lefcha 1.9 * Allocates memory for accounts, builds linked list, and NULL terminates
130 lefcha 1.8 * account settings.
131 lefcha 1.4 */
132 lefcha 1.8 account_t *prepare_account(void)
133 lefcha 1.4 {
134 lefcha 1.8 static account_t *ca; /* Current account. */
135    
136     if (!accounts) {
137     accounts = (account_t *) malloc(sizeof(account_t));
138 lefcha 1.9 if (!accounts) {
139     error("imapfilter: allocating memory; %s\n", strerror(errno));
140     return NULL;
141     }
142 lefcha 1.8 ca = accounts;
143     } else {
144     ca->next = (account_t *) malloc(sizeof(account_t));
145 lefcha 1.9 if (!ca->next) {
146     error("imapfilter: allocating memory; %s\n", strerror(errno));
147     return NULL;
148     }
149 lefcha 1.8 ca = ca->next;
150     }
151    
152     ca->next = NULL;
153    
154     ca->server[0] = 0;
155     ca->port = 143;
156     ca->userid[0] = 0;
157     ca->passwd[0] = 0;
158 lefcha 1.6
159 lefcha 1.8 return ca;
160 lefcha 1.4 }
161    
162    
163     /*
164 lefcha 1.1 * An account setting was found from parse_config(), changes the
165     * apropriate variable.
166     */
167 lefcha 1.9 int set_account(char *line, regmatch_t * match)
168 lefcha 1.1 {
169     int s;
170 lefcha 1.8 char p[6];
171     static account_t *ca;
172 lefcha 1.1
173     if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
174 lefcha 1.9 if (!(ca = prepare_account()))
175     return 1;
176 lefcha 1.1 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
177 lefcha 1.8 strncpy(ca->server, line + match[2].rm_so, s);
178     ca->server[s] = 0;
179 lefcha 1.6 #ifdef DEBUG
180 lefcha 1.8 printf("debug: account setting SERVER: '%s'\n", ca->server);
181 lefcha 1.6 #endif
182 lefcha 1.8 } else if (accounts) {
183 lefcha 1.6 if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
184 lefcha 1.8 s = min((match[2].rm_eo - match[2].rm_so), sizeof(p));
185     strncpy(p, line + match[2].rm_so, s);
186     p[s] = 0;
187     ca->port = strtoul(p, NULL, 0);
188 lefcha 1.6 #ifdef DEBUG
189 lefcha 1.8 printf("debug: account setting PORT: '%d'\n", ca->port);
190 lefcha 1.7 #endif
191 lefcha 1.6 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
192 lefcha 1.8 s = min((match[2].rm_eo - match[2].rm_so), USERID_MAX - 1);
193     strncpy(ca->userid, line + match[2].rm_so, s);
194     ca->userid[s] = 0;
195 lefcha 1.6 #ifdef DEBUG
196 lefcha 1.8 printf("debug: account setting USERNAME: '%s'\n", ca->userid);
197 lefcha 1.7 #endif
198 lefcha 1.6 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
199 lefcha 1.8 s = min((match[2].rm_eo - match[2].rm_so), PASSWD_MAX - 1);
200     strncpy(ca->passwd, line + match[2].rm_so, s);
201     ca->passwd[s] = 0;
202 lefcha 1.6 #ifdef DEBUG
203 lefcha 1.8 printf("debug: account setting PASSWORD: '%s'\n", ca->passwd);
204 lefcha 1.6 #endif
205     } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
206     s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
207     strncpy(logfile, line + match[2].rm_so, s);
208     logfile[s] = 0;
209     }
210 lefcha 1.1 }
211 lefcha 1.9
212     return 0;
213 lefcha 1.1 }
214    
215    
216     /*
217 lefcha 1.4 * A filter entry was found from parse_config() processes it and saves it.
218 lefcha 1.1 */
219 lefcha 1.9 int set_filters(char *line, regmatch_t * match, int csm)
220 lefcha 1.1 {
221     int s;
222 lefcha 1.8 static filter_t *cdf, *caf;
223     filter_t **cf;
224     filter_t **fl;
225 lefcha 1.2
226     if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
227     #ifdef DEBUG
228     printf("debug: filter entry: DENY");
229     #endif
230 lefcha 1.8 cf = &cdf;
231     fl = &dfilters;
232 lefcha 1.2 } else {
233     #ifdef DEBUG
234     printf("debug: filter entry: ALLOW");
235     #endif
236 lefcha 1.8 cf = &caf;
237     fl = &afilters;
238 lefcha 1.2 }
239 lefcha 1.1
240 lefcha 1.8 /*
241     * Allocate memory for filter entry and build linked list.
242     */
243    
244     if (!(*fl)) {
245     *fl = (filter_t *) malloc(sizeof(filter_t));
246 lefcha 1.9 if (!(*fl)) {
247     error("imapfilter: allocating memory; %s\n", strerror(errno));
248     return 1;
249     }
250 lefcha 1.8 *cf = *fl;
251     } else {
252     (*cf)->next = (filter_t *) malloc(sizeof(filter_t));
253 lefcha 1.9 if (!((*cf)->next)) {
254     error("imapfilter: allocating memory; %s\n", strerror(errno));
255     return 1;
256     }
257 lefcha 1.8 *cf = (*cf)->next;
258     }
259 lefcha 1.2
260 lefcha 1.8 (*cf)->next = NULL;
261 lefcha 1.2
262 lefcha 1.8 (*cf)->custom = csm;
263 lefcha 1.2
264     s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
265 lefcha 1.8 strncpy((*cf)->name, line + match[2].rm_so, s);
266     (*cf)->name[s] = 0;
267 lefcha 1.2
268     s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
269 lefcha 1.8 strncpy((*cf)->body, line + match[3].rm_so, s);
270     (*cf)->body[s] = 0;
271 lefcha 1.1
272     #ifdef DEBUG
273 lefcha 1.8 printf(" '%s': '%s'\n", (*cf)->name, (*cf)->body);
274 lefcha 1.1 #endif
275 lefcha 1.9 return 0;
276 lefcha 1.4 }
277    
278    
279     /*
280     * Sets the DENY and ALLOW limits from the values found in config file.
281     */
282     void set_limits(char *line, regmatch_t * match)
283     {
284     int s;
285 lefcha 1.8 char lim[10];
286 lefcha 1.4
287 lefcha 1.8 s = min((match[2].rm_eo - match[2].rm_so), sizeof(lim));
288     strncpy(lim, line + match[2].rm_so, s);
289     lim[s] = 0;
290 lefcha 1.4
291     if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
292 lefcha 1.8 dlimit = strtoul(lim, NULL, 0);
293 lefcha 1.4 } else {
294 lefcha 1.8 alimit = strtoul(lim, NULL, 0);
295 lefcha 1.4 }
296 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26