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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show 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 #include <stdio.h>
2 #include <errno.h>
3 #include <sys/types.h>
4 #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 extern char logfile[PATH_MAX];
16
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 unsigned int dlimit = 0;
23 unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
24
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
39 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 fprintf(stderr, "imapfilter: opening config file %s; %s\n",
51 cfg, strerror(errno));
52 return 1;
53 }
54
55 r = parse_config(fp);
56
57 fclose(fp);
58
59 return r;
60 }
61
62
63 /*
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 regex_t creg[5];
72 regmatch_t match[4];
73 const char *reg[5] = {
74 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
75 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
76 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
77 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
78 "^[[:blank:]]*#{0,1}.*"
79 };
80
81 for (i = 0; i < 5; i++)
82 regcomp(&creg[i], reg[i], REG_EXTENDED);
83
84 while (fgets(line, LINE_MAX - 1, fp)) {
85 row++;
86 if (!regexec(&creg[0], line, 3, match, 0)) {
87 if (set_account(line, match))
88 return 1;
89 continue;
90 } else if (!regexec(&creg[1], line, 4, match, 0)) {
91 if (standard_filter(line, match))
92 return 1;
93 continue;
94 } else if (!regexec(&creg[2], line, 4, match, 0)) {
95 if (custom_filter(line, match))
96 return 1;
97 continue;
98 } else if (!regexec(&creg[3], line, 3, match, 0)) {
99 set_limits(line, match);
100 continue;
101 } else if (!regexec(&creg[4], line, 1, match, 0))
102 continue;
103 else {
104 fprintf(stderr,
105 "imapfilter: parse error in config file at row %d\n",
106 row);
107 return 1;
108 }
109 }
110
111 /* Fail if no accounts were defined. */
112 if (!accounts) {
113 fprintf(stderr,
114 "imapfilter: no accounts defined in config file\n");
115 return 1;
116 }
117
118 /* Fail if no filters were defined. */
119 if (!dfilters && !afilters) {
120 fprintf(stderr, "imapfilter: no filters defined in config file\n");
121 return 1;
122 }
123
124 return 0;
125 }
126
127
128 /*
129 * Allocates memory for accounts, builds linked list, and NULL terminates
130 * account settings.
131 */
132 account_t *prepare_account(void)
133 {
134 static account_t *ca; /* Current account. */
135
136 if (!accounts) {
137 accounts = (account_t *) malloc(sizeof(account_t));
138 if (!accounts) {
139 error("imapfilter: allocating memory; %s\n", strerror(errno));
140 return NULL;
141 }
142 ca = accounts;
143 } else {
144 ca->next = (account_t *) malloc(sizeof(account_t));
145 if (!ca->next) {
146 error("imapfilter: allocating memory; %s\n", strerror(errno));
147 return NULL;
148 }
149 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
159 return ca;
160 }
161
162
163 /*
164 * An account setting was found from parse_config(), changes the
165 * apropriate variable.
166 */
167 int set_account(char *line, regmatch_t * match)
168 {
169 int s;
170 char p[6];
171 static account_t *ca;
172
173 if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
174 if (!(ca = prepare_account()))
175 return 1;
176 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
177 strncpy(ca->server, line + match[2].rm_so, s);
178 ca->server[s] = 0;
179 #ifdef DEBUG
180 printf("debug: account setting SERVER: '%s'\n", ca->server);
181 #endif
182 } else if (accounts) {
183 if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
184 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 #ifdef DEBUG
189 printf("debug: account setting PORT: '%d'\n", ca->port);
190 #endif
191 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
192 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 #ifdef DEBUG
196 printf("debug: account setting USERNAME: '%s'\n", ca->userid);
197 #endif
198 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
199 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 #ifdef DEBUG
203 printf("debug: account setting PASSWORD: '%s'\n", ca->passwd);
204 #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 }
211
212 return 0;
213 }
214
215
216 /*
217 * A filter entry was found from parse_config() processes it and saves it.
218 */
219 int set_filters(char *line, regmatch_t * match, int csm)
220 {
221 int s;
222 static filter_t *cdf, *caf;
223 filter_t **cf;
224 filter_t **fl;
225
226 if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
227 #ifdef DEBUG
228 printf("debug: filter entry: DENY");
229 #endif
230 cf = &cdf;
231 fl = &dfilters;
232 } else {
233 #ifdef DEBUG
234 printf("debug: filter entry: ALLOW");
235 #endif
236 cf = &caf;
237 fl = &afilters;
238 }
239
240 /*
241 * Allocate memory for filter entry and build linked list.
242 */
243
244 if (!(*fl)) {
245 *fl = (filter_t *) malloc(sizeof(filter_t));
246 if (!(*fl)) {
247 error("imapfilter: allocating memory; %s\n", strerror(errno));
248 return 1;
249 }
250 *cf = *fl;
251 } else {
252 (*cf)->next = (filter_t *) malloc(sizeof(filter_t));
253 if (!((*cf)->next)) {
254 error("imapfilter: allocating memory; %s\n", strerror(errno));
255 return 1;
256 }
257 *cf = (*cf)->next;
258 }
259
260 (*cf)->next = NULL;
261
262 (*cf)->custom = csm;
263
264 s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
265 strncpy((*cf)->name, line + match[2].rm_so, s);
266 (*cf)->name[s] = 0;
267
268 s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
269 strncpy((*cf)->body, line + match[3].rm_so, s);
270 (*cf)->body[s] = 0;
271
272 #ifdef DEBUG
273 printf(" '%s': '%s'\n", (*cf)->name, (*cf)->body);
274 #endif
275 return 0;
276 }
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 char lim[10];
286
287 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
291 if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
292 dlimit = strtoul(lim, NULL, 0);
293 } else {
294 alimit = strtoul(lim, NULL, 0);
295 }
296 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26