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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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 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 in the configuration file. */
20 unsigned int dlimit = 0;
21 unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
22
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 regex_t comreg[5];
68 regmatch_t match[4];
69 const char *reg[5] = {
70 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
71 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
72 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
73 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
74 "^[[:blank:]]*#{0,1}.*"
75 };
76
77 for (i = 0; i < 5; i++)
78 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 } else if (!regexec(&comreg[1], line, 4, match, 0)) {
86 standard_filter(line, match);
87 continue;
88 } else if (!regexec(&comreg[2], line, 4, match, 0)) {
89 custom_filter(line, match);
90 continue;
91 } 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 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
104 /* Fail if no filters were defined. */
105 if (!dfcnt && !afcnt) {
106 fprintf(stderr, "imapfilter: no filters defined in config file\n");
107 return FAILURE;
108 }
109 #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 "debug: account setting LOGFILE: '%s'\n"
115 "debug: setting DENY_LIMIT: %d\n"
116 "debug: setting ALLOW_LIMIT: %d\n",
117 account.server, account.port, account.username,
118 account.password, account.logfile, dlimit, alimit);
119 #endif
120 return SUCCESS;
121 }
122
123
124 /*
125 * 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 * 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 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 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 * A filter entry was found from parse_config() processes it and saves it.
173 */
174 void set_filters(char *line, regmatch_t * match, int expl)
175 {
176 int s;
177 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
194 /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */
195 if (!*fcnt)
196 *filters =
197 (filter_entry **) malloc(FILTER_ENTRIES_MAX *
198 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
218 #ifdef DEBUG
219 printf(" '%s': '%s'\n", (*filters)[*fcnt]->name,
220 (*filters)[*fcnt]->body);
221 #endif
222
223 (*fcnt)++;
224 }
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 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26