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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Tue Aug 21 23:28:36 2001 UTC (22 years, 8 months ago) by lefcha
Branch: MAIN
Changes since 1.4: +1 -0 lines
File MIME type: text/plain
Fixed bug to compile properly under BSD

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 account_data account;
16 filter_entry **dfilters; /* Filters of DENY type. */
17 filter_entry **afilters; /* Filters of ALLOW type. */
18 int dfcnt = 0;
19 int afcnt = 0; /* DENY and ALLOW type filters found
20 in the configuration file. */
21 unsigned int dlimit = 0;
22 unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
23
24
25 /*
26 * Finds path to configuration file, opens it and calls parse_config().
27 */
28 int read_config(char *cfg)
29 {
30 int r;
31 FILE *fp;
32 char *home = NULL;
33
34 if (!cfg) {
35 cfg = (char *) malloc(PATH_MAX * sizeof(char));
36
37 home = getenv("HOME");
38
39 snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");
40 }
41 #ifdef DEBUG
42 printf("debug: configuration file: %s\n", cfg);
43 #endif
44
45 fp = fopen(cfg, "r");
46
47 if (!fp) {
48 fprintf(stderr, "imapfilter: Could not open config file %s; %s\n",
49 cfg, strerror(errno));
50 return FAILURE;
51 }
52
53 r = parse_config(fp);
54
55 fclose(fp);
56
57 return r;
58 }
59
60 /*
61 * Parses configuration file.
62 */
63 int parse_config(FILE * fp)
64 {
65 int i;
66 unsigned int row = 0;
67 char line[LINE_MAX];
68 regex_t comreg[5];
69 regmatch_t match[4];
70 const char *reg[5] = {
71 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
72 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
73 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
74 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
75 "^[[:blank:]]*#{0,1}.*"
76 };
77
78 for (i = 0; i < 5; i++)
79 regcomp(&comreg[i], reg[i], REG_EXTENDED);
80
81 while (fgets(line, LINE_MAX - 1, fp)) {
82 row++;
83 if (!regexec(&comreg[0], line, 3, match, 0)) {
84 set_account(line, match);
85 continue;
86 } else if (!regexec(&comreg[1], line, 4, match, 0)) {
87 standard_filter(line, match);
88 continue;
89 } else if (!regexec(&comreg[2], line, 4, match, 0)) {
90 custom_filter(line, match);
91 continue;
92 } else if (!regexec(&comreg[3], line, 3, match, 0)) {
93 set_limits(line, match);
94 continue;
95 } else if (!regexec(&comreg[4], line, 1, match, 0))
96 continue;
97 else {
98 fprintf(stderr,
99 "imapfilter: parse error in config file at row %d\n",
100 row);
101 return FAILURE;
102 }
103 }
104
105 /* Fail if no filters were defined. */
106 if (!dfcnt && !afcnt) {
107 fprintf(stderr, "imapfilter: no filters defined in config file\n");
108 return FAILURE;
109 }
110 #ifdef DEBUG
111 printf("debug: account setting SERVER: '%s'\n"
112 "debug: account setting PORT: %d\n"
113 "debug: account setting USERNAME: '%s'\n"
114 "debug: account setting PASSWORD: '%s'\n"
115 "debug: account setting LOGFILE: '%s'\n"
116 "debug: setting DENY_LIMIT: %d\n"
117 "debug: setting ALLOW_LIMIT: %d\n",
118 account.server, account.port, account.username,
119 account.password, account.logfile, dlimit, alimit);
120 #endif
121 return SUCCESS;
122 }
123
124
125 /*
126 * NULL terminate account settings.
127 */
128 void prepare_account(void)
129 {
130 account.server[0] = 0;
131 account.port = 143;
132 account.username[0] = 0;
133 account.password[0] = 0;
134 account.logfile[0] = 0;
135 }
136
137
138 /*
139 * An account setting was found from parse_config(), changes the
140 * apropriate variable.
141 */
142 void set_account(char *line, regmatch_t * match)
143 {
144 int s;
145 char port[6];
146
147 if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
148 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
149 strncpy(account.server, line + match[2].rm_so, s);
150 account.server[s] = 0;
151 } else if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
152 s = min((match[2].rm_eo - match[2].rm_so), sizeof(port));
153 strncpy(port, line + match[2].rm_so, s);
154 port[s] = 0;
155 account.port = strtoul(port, NULL, 0);
156 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
157 s = min((match[2].rm_eo - match[2].rm_so), USERNAME_MAX - 1);
158 strncpy(account.username, line + match[2].rm_so, s);
159 account.username[s] = 0;
160 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
161 s = min((match[2].rm_eo - match[2].rm_so), PASSWORD_MAX - 1);
162 strncpy(account.password, line + match[2].rm_so, s);
163 account.password[s] = 0;
164 } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
165 s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
166 strncpy(account.logfile, line + match[2].rm_so, s);
167 account.logfile[s] = 0;
168 }
169 }
170
171
172 /*
173 * A filter entry was found from parse_config() processes it and saves it.
174 */
175 void set_filters(char *line, regmatch_t * match, int expl)
176 {
177 int s;
178 int *fcnt;
179 filter_entry ***filters;
180
181 if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
182 #ifdef DEBUG
183 printf("debug: filter entry: DENY");
184 #endif
185 fcnt = &dfcnt;
186 filters = &dfilters;
187 } else {
188 #ifdef DEBUG
189 printf("debug: filter entry: ALLOW");
190 #endif
191 fcnt = &afcnt;
192 filters = &afilters;
193 }
194
195 /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */
196 if (!*fcnt)
197 *filters =
198 (filter_entry **) malloc(FILTER_ENTRIES_MAX *
199 sizeof(filter_entry *));
200 else if (!(*fcnt % FILTER_ENTRIES_MAX))
201 *filters = (filter_entry **) realloc(*filters,
202 (((*fcnt /
203 FILTER_ENTRIES_MAX) +
204 1) * FILTER_ENTRIES_MAX) *
205 sizeof(filter_entry *));
206
207 (*filters)[*fcnt] = (filter_entry *) malloc(sizeof(filter_entry));
208
209 (*filters)[*fcnt]->custom = expl;
210
211 s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
212 strncpy((*filters)[*fcnt]->name, line + match[2].rm_so, s);
213 (*filters)[*fcnt]->name[s] = 0;
214
215 s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
216 strncpy((*filters)[*fcnt]->body, line + match[3].rm_so, s);
217 (*filters)[*fcnt]->body[s] = 0;
218
219 #ifdef DEBUG
220 printf(" '%s': '%s'\n", (*filters)[*fcnt]->name,
221 (*filters)[*fcnt]->body);
222 #endif
223
224 (*fcnt)++;
225 }
226
227
228 /*
229 * Sets the DENY and ALLOW limits from the values found in config file.
230 */
231 void set_limits(char *line, regmatch_t * match)
232 {
233 int s;
234 char limit[10];
235
236 s = min((match[2].rm_eo - match[2].rm_so), sizeof(limit));
237 strncpy(limit, line + match[2].rm_so, s);
238 limit[s] = 0;
239
240 if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
241 dlimit = strtoul(limit, NULL, 0);
242 } else {
243 alimit = strtoul(limit, NULL, 0);
244 }
245 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26