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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide 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 lefcha 1.1 #include <stdio.h>
2     #include <errno.h>
3 lefcha 1.5 #include <sys/types.h>
4 lefcha 1.1 #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 lefcha 1.6 extern char logfile[PATH_MAX];
16     account_data **accounts;
17     int acccnt = -1; /* Accounts declared. */
18 lefcha 1.2 filter_entry **dfilters; /* Filters of DENY type. */
19     filter_entry **afilters; /* Filters of ALLOW type. */
20 lefcha 1.6 int dfilcnt = 0;
21     int afilcnt = 0; /* DENY and ALLOW type filters found
22 lefcha 1.4 in the configuration file. */
23     unsigned int dlimit = 0;
24     unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
25 lefcha 1.1
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 lefcha 1.7 fprintf(stderr, "imapfilter: opening config file %s; %s\n",
51 lefcha 1.1 cfg, strerror(errno));
52     return FAILURE;
53     }
54    
55     r = parse_config(fp);
56    
57     fclose(fp);
58    
59     return r;
60     }
61    
62 lefcha 1.6
63 lefcha 1.1 /*
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 lefcha 1.7 regex_t compexp[5];
72 lefcha 1.2 regmatch_t match[4];
73 lefcha 1.4 const char *reg[5] = {
74 lefcha 1.1 "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",
75 lefcha 1.2 "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",
76     "^[[:blank:]]*(DENY|ALLOW)[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",
77 lefcha 1.4 "^[[:blank:]]*(DENY_LIMIT|ALLOW_LIMIT)[[:blank:]]*=[[:blank:]]*([[:digit:]]*)[[:blank:]]*",
78 lefcha 1.1 "^[[:blank:]]*#{0,1}.*"
79     };
80    
81 lefcha 1.4 for (i = 0; i < 5; i++)
82 lefcha 1.7 regcomp(&compexp[i], reg[i], REG_EXTENDED);
83 lefcha 1.1
84     while (fgets(line, LINE_MAX - 1, fp)) {
85     row++;
86 lefcha 1.7 if (!regexec(&compexp[0], line, 3, match, 0)) {
87 lefcha 1.1 set_account(line, match);
88     continue;
89 lefcha 1.7 } else if (!regexec(&compexp[1], line, 4, match, 0)) {
90 lefcha 1.1 standard_filter(line, match);
91     continue;
92 lefcha 1.7 } else if (!regexec(&compexp[2], line, 4, match, 0)) {
93 lefcha 1.2 custom_filter(line, match);
94 lefcha 1.1 continue;
95 lefcha 1.7 } else if (!regexec(&compexp[3], line, 3, match, 0)) {
96 lefcha 1.4 set_limits(line, match);
97     continue;
98 lefcha 1.7 } else if (!regexec(&compexp[4], line, 1, match, 0))
99 lefcha 1.1 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 lefcha 1.3
108 lefcha 1.6 /* 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 lefcha 1.3 fprintf(stderr, "imapfilter: no filters defined in config file\n");
118     return FAILURE;
119     }
120 lefcha 1.6
121 lefcha 1.1 return SUCCESS;
122     }
123    
124    
125     /*
126 lefcha 1.6 * Allocate memory for accounts and NULL terminate account settings.
127 lefcha 1.4 */
128     void prepare_account(void)
129     {
130 lefcha 1.6 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 lefcha 1.4 }
145    
146    
147     /*
148 lefcha 1.1 * 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 lefcha 1.6 prepare_account();
158 lefcha 1.1 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
159 lefcha 1.6 strncpy(accounts[acccnt]->server, line + match[2].rm_so, s);
160     accounts[acccnt]->server[s] = 0;
161     #ifdef DEBUG
162 lefcha 1.7 printf("debug: account setting SERVER: '%s'\n",
163     accounts[acccnt]->server);
164 lefcha 1.6 #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 lefcha 1.7 printf("debug: account setting PORT: '%d'\n",
173     accounts[acccnt]->port);
174     #endif
175 lefcha 1.6 } 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 lefcha 1.7 printf("debug: account setting USERNAME: '%s'\n",
181     accounts[acccnt]->username);
182     #endif
183 lefcha 1.6 } 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 lefcha 1.7 printf("debug: account setting PASSWORD: '%s'\n",
189     accounts[acccnt]->password);
190 lefcha 1.6 #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 lefcha 1.1 }
197     }
198    
199    
200     /*
201 lefcha 1.4 * A filter entry was found from parse_config() processes it and saves it.
202 lefcha 1.1 */
203     void set_filters(char *line, regmatch_t * match, int expl)
204     {
205     int s;
206 lefcha 1.2 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 lefcha 1.6 fcnt = &dfilcnt;
214 lefcha 1.2 filters = &dfilters;
215     } else {
216     #ifdef DEBUG
217     printf("debug: filter entry: ALLOW");
218     #endif
219 lefcha 1.6 fcnt = &afilcnt;
220 lefcha 1.2 filters = &afilters;
221     }
222 lefcha 1.1
223     /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */
224 lefcha 1.2 if (!*fcnt)
225     *filters =
226 lefcha 1.1 (filter_entry **) malloc(FILTER_ENTRIES_MAX *
227 lefcha 1.2 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 lefcha 1.1
247     #ifdef DEBUG
248 lefcha 1.2 printf(" '%s': '%s'\n", (*filters)[*fcnt]->name,
249     (*filters)[*fcnt]->body);
250 lefcha 1.1 #endif
251    
252 lefcha 1.2 (*fcnt)++;
253 lefcha 1.4 }
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 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26