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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Fri Aug 24 17:42:49 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.6: +18 -14 lines
File MIME type: text/plain
Printing of an info message and other small 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 account_data **accounts;
17 int acccnt = -1; /* Accounts declared. */
18 filter_entry **dfilters; /* Filters of DENY type. */
19 filter_entry **afilters; /* Filters of ALLOW type. */
20 int dfilcnt = 0;
21 int afilcnt = 0; /* DENY and ALLOW type filters found
22 in the configuration file. */
23 unsigned int dlimit = 0;
24 unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
25
26
27 /*
28 * Finds path to configuration file, opens it and calls parse_config().
29 */
30 int read_config(char *cfg)
31 {
32 int r;
33 FILE *fp;
34 char *home = NULL;
35
36 if (!cfg) {
37 cfg = (char *) malloc(PATH_MAX * sizeof(char));
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 FAILURE;
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 compexp[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(&compexp[i], reg[i], REG_EXTENDED);
83
84 while (fgets(line, LINE_MAX - 1, fp)) {
85 row++;
86 if (!regexec(&compexp[0], line, 3, match, 0)) {
87 set_account(line, match);
88 continue;
89 } else if (!regexec(&compexp[1], line, 4, match, 0)) {
90 standard_filter(line, match);
91 continue;
92 } else if (!regexec(&compexp[2], line, 4, match, 0)) {
93 custom_filter(line, match);
94 continue;
95 } else if (!regexec(&compexp[3], line, 3, match, 0)) {
96 set_limits(line, match);
97 continue;
98 } else if (!regexec(&compexp[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 FAILURE;
105 }
106 }
107
108 /* Fail if no accounts were defined. */
109 if (acccnt == -1) {
110 fprintf(stderr,
111 "imapfilter: no accounts defined in config file\n");
112 return FAILURE;
113 }
114
115 /* Fail if no fitlers were defined. */
116 if (!dfilcnt && !afilcnt) {
117 fprintf(stderr, "imapfilter: no filters defined in config file\n");
118 return FAILURE;
119 }
120
121 return SUCCESS;
122 }
123
124
125 /*
126 * Allocate memory for accounts and NULL terminate account settings.
127 */
128 void prepare_account(void)
129 {
130 acccnt++;
131
132 if (!acccnt)
133 accounts = (account_data **) malloc(sizeof(account_data *));
134 else
135 accounts = (account_data **) realloc(accounts, (acccnt + 1) *
136 sizeof(account_data *));
137
138 accounts[acccnt] = (account_data *) malloc(sizeof(account_data));
139
140 accounts[acccnt]->server[0] = 0;
141 accounts[acccnt]->port = 143;
142 accounts[acccnt]->username[0] = 0;
143 accounts[acccnt]->password[0] = 0;
144 }
145
146
147 /*
148 * An account setting was found from parse_config(), changes the
149 * apropriate variable.
150 */
151 void set_account(char *line, regmatch_t * match)
152 {
153 int s;
154 char port[6];
155
156 if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
157 prepare_account();
158 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
159 strncpy(accounts[acccnt]->server, line + match[2].rm_so, s);
160 accounts[acccnt]->server[s] = 0;
161 #ifdef DEBUG
162 printf("debug: account setting SERVER: '%s'\n",
163 accounts[acccnt]->server);
164 #endif
165 } else if (acccnt >= 0) {
166 if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
167 s = min((match[2].rm_eo - match[2].rm_so), sizeof(port));
168 strncpy(port, line + match[2].rm_so, s);
169 port[s] = 0;
170 accounts[acccnt]->port = strtoul(port, NULL, 0);
171 #ifdef DEBUG
172 printf("debug: account setting PORT: '%d'\n",
173 accounts[acccnt]->port);
174 #endif
175 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
176 s = min((match[2].rm_eo - match[2].rm_so), USERNAME_MAX - 1);
177 strncpy(accounts[acccnt]->username, line + match[2].rm_so, s);
178 accounts[acccnt]->username[s] = 0;
179 #ifdef DEBUG
180 printf("debug: account setting USERNAME: '%s'\n",
181 accounts[acccnt]->username);
182 #endif
183 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
184 s = min((match[2].rm_eo - match[2].rm_so), PASSWORD_MAX - 1);
185 strncpy(accounts[acccnt]->password, line + match[2].rm_so, s);
186 accounts[acccnt]->password[s] = 0;
187 #ifdef DEBUG
188 printf("debug: account setting PASSWORD: '%s'\n",
189 accounts[acccnt]->password);
190 #endif
191 } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
192 s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
193 strncpy(logfile, line + match[2].rm_so, s);
194 logfile[s] = 0;
195 }
196 }
197 }
198
199
200 /*
201 * A filter entry was found from parse_config() processes it and saves it.
202 */
203 void set_filters(char *line, regmatch_t * match, int expl)
204 {
205 int s;
206 int *fcnt;
207 filter_entry ***filters;
208
209 if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
210 #ifdef DEBUG
211 printf("debug: filter entry: DENY");
212 #endif
213 fcnt = &dfilcnt;
214 filters = &dfilters;
215 } else {
216 #ifdef DEBUG
217 printf("debug: filter entry: ALLOW");
218 #endif
219 fcnt = &afilcnt;
220 filters = &afilters;
221 }
222
223 /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */
224 if (!*fcnt)
225 *filters =
226 (filter_entry **) malloc(FILTER_ENTRIES_MAX *
227 sizeof(filter_entry *));
228 else if (!(*fcnt % FILTER_ENTRIES_MAX))
229 *filters = (filter_entry **) realloc(*filters,
230 (((*fcnt /
231 FILTER_ENTRIES_MAX) +
232 1) * FILTER_ENTRIES_MAX) *
233 sizeof(filter_entry *));
234
235 (*filters)[*fcnt] = (filter_entry *) malloc(sizeof(filter_entry));
236
237 (*filters)[*fcnt]->custom = expl;
238
239 s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
240 strncpy((*filters)[*fcnt]->name, line + match[2].rm_so, s);
241 (*filters)[*fcnt]->name[s] = 0;
242
243 s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
244 strncpy((*filters)[*fcnt]->body, line + match[3].rm_so, s);
245 (*filters)[*fcnt]->body[s] = 0;
246
247 #ifdef DEBUG
248 printf(" '%s': '%s'\n", (*filters)[*fcnt]->name,
249 (*filters)[*fcnt]->body);
250 #endif
251
252 (*fcnt)++;
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 limit[10];
263
264 s = min((match[2].rm_eo - match[2].rm_so), sizeof(limit));
265 strncpy(limit, line + match[2].rm_so, s);
266 limit[s] = 0;
267
268 if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
269 dlimit = strtoul(limit, NULL, 0);
270 } else {
271 alimit = strtoul(limit, NULL, 0);
272 }
273 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26