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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26