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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide 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 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 lefcha 1.8
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 lefcha 1.4 unsigned int dlimit = 0;
23     unsigned int alimit = 0; /* DENY and ALLOW message size limits. */
24 lefcha 1.1
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 lefcha 1.8
39 lefcha 1.1 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 lefcha 1.8 return 1;
53 lefcha 1.1 }
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.8 regex_t creg[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.8 regcomp(&creg[i], reg[i], REG_EXTENDED);
83 lefcha 1.1
84     while (fgets(line, LINE_MAX - 1, fp)) {
85     row++;
86 lefcha 1.8 if (!regexec(&creg[0], line, 3, match, 0)) {
87 lefcha 1.1 set_account(line, match);
88     continue;
89 lefcha 1.8 } else if (!regexec(&creg[1], line, 4, match, 0)) {
90 lefcha 1.1 standard_filter(line, match);
91     continue;
92 lefcha 1.8 } else if (!regexec(&creg[2], line, 4, match, 0)) {
93 lefcha 1.2 custom_filter(line, match);
94 lefcha 1.1 continue;
95 lefcha 1.8 } else if (!regexec(&creg[3], line, 3, match, 0)) {
96 lefcha 1.4 set_limits(line, match);
97     continue;
98 lefcha 1.8 } else if (!regexec(&creg[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 lefcha 1.8 return 1;
105 lefcha 1.1 }
106     }
107 lefcha 1.3
108 lefcha 1.6 /* Fail if no accounts were defined. */
109 lefcha 1.8 if (!accounts) {
110 lefcha 1.6 fprintf(stderr,
111     "imapfilter: no accounts defined in config file\n");
112 lefcha 1.8 return 1;
113 lefcha 1.6 }
114    
115 lefcha 1.8 /* Fail if no filters were defined. */
116     if (!dfilters && !afilters) {
117 lefcha 1.3 fprintf(stderr, "imapfilter: no filters defined in config file\n");
118 lefcha 1.8 return 1;
119 lefcha 1.3 }
120 lefcha 1.6
121 lefcha 1.8 return 0;
122 lefcha 1.1 }
123    
124    
125     /*
126 lefcha 1.8 * Allocate memory for accounts, build linked list, and NULL terminate
127     * account settings.
128 lefcha 1.4 */
129 lefcha 1.8 account_t *prepare_account(void)
130 lefcha 1.4 {
131 lefcha 1.8 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 lefcha 1.6
148 lefcha 1.8 return ca;
149 lefcha 1.4 }
150    
151    
152     /*
153 lefcha 1.1 * 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 lefcha 1.8 char p[6];
160     static account_t *ca;
161 lefcha 1.1
162     if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {
163 lefcha 1.8 ca = prepare_account();
164 lefcha 1.1 s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);
165 lefcha 1.8 strncpy(ca->server, line + match[2].rm_so, s);
166     ca->server[s] = 0;
167 lefcha 1.6 #ifdef DEBUG
168 lefcha 1.8 printf("debug: account setting SERVER: '%s'\n", ca->server);
169 lefcha 1.6 #endif
170 lefcha 1.8 } else if (accounts) {
171 lefcha 1.6 if (!strncmp(line + match[1].rm_so, "PORT", 4)) {
172 lefcha 1.8 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 lefcha 1.6 #ifdef DEBUG
177 lefcha 1.8 printf("debug: account setting PORT: '%d'\n", ca->port);
178 lefcha 1.7 #endif
179 lefcha 1.6 } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {
180 lefcha 1.8 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 lefcha 1.6 #ifdef DEBUG
184 lefcha 1.8 printf("debug: account setting USERNAME: '%s'\n", ca->userid);
185 lefcha 1.7 #endif
186 lefcha 1.6 } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {
187 lefcha 1.8 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 lefcha 1.6 #ifdef DEBUG
191 lefcha 1.8 printf("debug: account setting PASSWORD: '%s'\n", ca->passwd);
192 lefcha 1.6 #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 lefcha 1.1 }
199     }
200    
201    
202     /*
203 lefcha 1.4 * A filter entry was found from parse_config() processes it and saves it.
204 lefcha 1.1 */
205 lefcha 1.8 void set_filters(char *line, regmatch_t * match, int csm)
206 lefcha 1.1 {
207     int s;
208 lefcha 1.8 static filter_t *cdf, *caf;
209     filter_t **cf;
210     filter_t **fl;
211 lefcha 1.2
212     if (!(strncmp(line + match[1].rm_so, "DENY", 4))) {
213     #ifdef DEBUG
214     printf("debug: filter entry: DENY");
215     #endif
216 lefcha 1.8 cf = &cdf;
217     fl = &dfilters;
218 lefcha 1.2 } else {
219     #ifdef DEBUG
220     printf("debug: filter entry: ALLOW");
221     #endif
222 lefcha 1.8 cf = &caf;
223     fl = &afilters;
224 lefcha 1.2 }
225 lefcha 1.1
226 lefcha 1.8 /*
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 lefcha 1.2
238 lefcha 1.8 (*cf)->next = NULL;
239 lefcha 1.2
240 lefcha 1.8 (*cf)->custom = csm;
241 lefcha 1.2
242     s = min((match[2].rm_eo - match[2].rm_so), FIELD_NAME_MAX - 1);
243 lefcha 1.8 strncpy((*cf)->name, line + match[2].rm_so, s);
244     (*cf)->name[s] = 0;
245 lefcha 1.2
246     s = min((match[3].rm_eo - match[3].rm_so), FIELD_BODY_MAX - 1);
247 lefcha 1.8 strncpy((*cf)->body, line + match[3].rm_so, s);
248     (*cf)->body[s] = 0;
249 lefcha 1.1
250     #ifdef DEBUG
251 lefcha 1.8 printf(" '%s': '%s'\n", (*cf)->name, (*cf)->body);
252 lefcha 1.1 #endif
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 lefcha 1.8 char lim[10];
263 lefcha 1.4
264 lefcha 1.8 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 lefcha 1.4
268     if (!strncmp(line + match[1].rm_so, "DENY_LIMIT", 10)) {
269 lefcha 1.8 dlimit = strtoul(lim, NULL, 0);
270 lefcha 1.4 } else {
271 lefcha 1.8 alimit = strtoul(lim, NULL, 0);
272 lefcha 1.4 }
273 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26