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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations)
Sun Aug 26 01:18:24 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.7: +94 -94 lines
File MIME type: text/plain
Structural changes

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 set_account(line, match);
88 continue;
89 } else if (!regexec(&creg[1], line, 4, match, 0)) {
90 standard_filter(line, match);
91 continue;
92 } else if (!regexec(&creg[2], line, 4, match, 0)) {
93 custom_filter(line, match);
94 continue;
95 } else if (!regexec(&creg[3], line, 3, match, 0)) {
96 set_limits(line, match);
97 continue;
98 } else if (!regexec(&creg[4], line, 1, match, 0))
99 continue;
100 else {
101 fprintf(stderr,
102 "imapfilter: parse error in config file at row %d\n",
103 row);
104 return 1;
105 }
106 }
107
108 /* Fail if no accounts were defined. */
109 if (!accounts) {
110 fprintf(stderr,
111 "imapfilter: no accounts defined in config file\n");
112 return 1;
113 }
114
115 /* Fail if no filters were defined. */
116 if (!dfilters && !afilters) {
117 fprintf(stderr, "imapfilter: no filters defined in config file\n");
118 return 1;
119 }
120
121 return 0;
122 }
123
124
125 /*
126 * Allocate memory for accounts, build linked list, and NULL terminate
127 * account settings.
128 */
129 account_t *prepare_account(void)
130 {
131 static account_t *ca; /* Current account. */
132
133 if (!accounts) {
134 accounts = (account_t *) malloc(sizeof(account_t));
135 ca = accounts;
136 } else {
137 ca->next = (account_t *) malloc(sizeof(account_t));
138 ca = ca->next;
139 }
140
141 ca->next = NULL;
142
143 ca->server[0] = 0;
144 ca->port = 143;
145 ca->userid[0] = 0;
146 ca->passwd[0] = 0;
147
148 return ca;
149 }
150
151
152 /*
153 * An account setting was found from parse_config(), changes the
154 * apropriate variable.
155 */
156 void set_account(char *line, regmatch_t * match)
157 {
158 int s;
159 char p[6];
160 static account_t *ca;
161
162 if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
163 ca = prepare_account();
164 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
165 strncpy(ca->server, line + match[2].rm_so, s);
166 ca->server[s] = 0;
167 #ifdef DEBUG
168 printf("debug: account setting SERVER: '%s'\n", ca->server);
169 #endif
170 } else if (accounts) {
171 if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
172 s = min((match[2].rm_eo - match[2].rm_so), sizeof(p));
173 strncpy(p, line + match[2].rm_so, s);
174 p[s] = 0;
175 ca->port = strtoul(p, NULL, 0);
176 #ifdef DEBUG
177 printf("debug: account setting PORT: '%d'\n", ca->port);
178 #endif
179 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
180 s = min((match[2].rm_eo - match[2].rm_so), USERID_MAX - 1);
181 strncpy(ca->userid, line + match[2].rm_so, s);
182 ca->userid[s] = 0;
183 #ifdef DEBUG
184 printf("debug: account setting USERNAME: '%s'\n", ca->userid);
185 #endif
186 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
187 s = min((match[2].rm_eo - match[2].rm_so), PASSWD_MAX - 1);
188 strncpy(ca->passwd, line + match[2].rm_so, s);
189 ca->passwd[s] = 0;
190 #ifdef DEBUG
191 printf("debug: account setting PASSWORD: '%s'\n", ca->passwd);
192 #endif
193 } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
194 s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
195 strncpy(logfile, line + match[2].rm_so, s);
196 logfile[s] = 0;
197 }
198 }
199 }
200
201
202 /*
203 * A filter entry was found from parse_config() processes it and saves it.
204 */
205 void set_filters(char *line, regmatch_t * match, int csm)
206 {
207 int s;
208 static filter_t *cdf, *caf;
209 filter_t **cf;
210 filter_t **fl;
211
212 if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
213 #ifdef DEBUG
214 printf("debug: filter entry: DENY");
215 #endif
216 cf = &cdf;
217 fl = &dfilters;
218 } else {
219 #ifdef DEBUG
220 printf("debug: filter entry: ALLOW");
221 #endif
222 cf = &caf;
223 fl = &afilters;
224 }
225
226 /*
227 * Allocate memory for filter entry and build linked list.
228 */
229
230 if (!(*fl)) {
231 *fl = (filter_t *) malloc(sizeof(filter_t));
232 *cf = *fl;
233 } else {
234 (*cf)->next = (filter_t *) malloc(sizeof(filter_t));
235 *cf = (*cf)->next;
236 }
237
238 (*cf)->next = NULL;
239
240 (*cf)->custom = csm;
241
242 s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
243 strncpy((*cf)->name, line + match[2].rm_so, s);
244 (*cf)->name[s] = 0;
245
246 s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
247 strncpy((*cf)->body, line + match[3].rm_so, s);
248 (*cf)->body[s] = 0;
249
250 #ifdef DEBUG
251 printf(" '%s': '%s'\n", (*cf)->name, (*cf)->body);
252 #endif
253 }
254
255
256 /*
257 * Sets the DENY and ALLOW limits from the values found in config file.
258 */
259 void set_limits(char *line, regmatch_t * match)
260 {
261 int s;
262 char lim[10];
263
264 s = min((match[2].rm_eo - match[2].rm_so), sizeof(lim));
265 strncpy(lim, line + match[2].rm_so, s);
266 lim[s] = 0;
267
268 if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
269 dlimit = strtoul(lim, NULL, 0);
270 } else {
271 alimit = strtoul(lim, NULL, 0);
272 }
273 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26