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

Annotation of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.28 - (hide annotations)
Sat Dec 8 14:39:10 2001 UTC (22 years, 3 months ago) by lefcha
Branch: MAIN
Changes since 1.27: +140 -35 lines
File MIME type: text/plain
Added functions for creation and checking of dirs and files.

1 lefcha 1.1 #include <stdio.h>
2 lefcha 1.28 #include <unistd.h>
3 lefcha 1.1 #include <errno.h>
4 lefcha 1.5 #include <sys/types.h>
5 lefcha 1.1 #include <regex.h>
6     #include <string.h>
7     #include <stdlib.h>
8     #include <limits.h>
9 lefcha 1.10 #include <sys/stat.h>
10 lefcha 1.28 #include <fcntl.h>
11 lefcha 1.1
12     #include "config.h"
13     #include "imapfilter.h"
14 lefcha 1.13 #include "data.h"
15 lefcha 1.1
16    
17 lefcha 1.6 extern char logfile[PATH_MAX];
18 lefcha 1.11 extern unsigned int options;
19 lefcha 1.28 extern long timeout;
20 lefcha 1.8
21 lefcha 1.28
22     /*
23     * Create $HOME/.imapfilter directory.
24     */
25     int create_homedir(void)
26     {
27     char *hdname = ".imapfilter";
28     char *home = NULL;
29    
30     home = getenv("HOME");
31    
32     if (home)
33     if (chdir(home))
34     error("imapfilter: could not change directory; %s\n",
35     strerror(errno));
36    
37     create_dir(hdname, S_IRUSR | S_IWUSR | S_IXUSR);
38    
39     return 0;
40     }
41    
42    
43     /*
44     * Create a file.
45     */
46     int create_file(char *fname, mode_t mode)
47     {
48     int fd;
49     struct stat fs;
50    
51     if (access(fname, F_OK)) {
52     fd = creat(fname, mode);
53     if (fd == -1) {
54     error("imapfilter: could not create file %s; %s\n", fname,
55     strerror(errno));
56     return ERROR_FILE_OPEN;
57     }
58     close(fd);
59     } else {
60     stat(fname, &fs);
61     if (!S_ISREG(fs.st_mode)) {
62     error("imapfilter: file %s not a regular file\n", fname);
63     return ERROR_FILE_OPEN;
64     }
65     }
66    
67     return 0;
68     }
69    
70    
71     /*
72     * Create a directory.
73     */
74     int create_dir(char *dname, mode_t mode)
75     {
76     struct stat ds;
77    
78     if (access(dname, F_OK)) {
79     if (mkdir(dname, mode))
80     error("imapfilter: could not create directory %s; %s\n", dname,
81     strerror(errno));
82     } else {
83     stat(dname, &ds);
84     if (!S_ISDIR(ds.st_mode))
85     error("imapfilter: file %s not a directory\n", dname);
86     }
87    
88     return 0;
89     }
90    
91    
92     #ifdef CHECK_PERMISSIONS
93     /*
94     * Check the permissions of a file.
95     */
96     int check_file_perms(char *fname, mode_t mode)
97     {
98     struct stat fs;
99    
100     if (stat(fname, &fs)) {
101     error("imapfilter: getting file %s status; %s\n", fname,
102     strerror(errno));
103     return ERROR_TRIVIAL;
104     }
105     if (!S_ISREG(fs.st_mode)) {
106     error("imapfilter: file %s not a regular file\n", fname);
107     return ERROR_TRIVIAL;
108     }
109     if ((fs.st_mode & 00777) != mode) {
110     error("imapfilter: warning: improper file %s permissions\n"
111     "imapfilter: warning: file's mode should be %o not %o\n",
112     fname, mode, fs.st_mode & 00777);
113     return ERROR_TRIVIAL;
114     }
115    
116     return 0;
117     }
118    
119    
120     /*
121     * Check the permissions of a directory.
122     */
123     int check_dir_perms(char *dname, mode_t mode)
124     {
125     struct stat ds;
126    
127     if(stat(dname, &ds)) {
128     error("imapfilter: getting file %s status; %s\n", dname,
129     strerror(errno));
130     return ERROR_TRIVIAL;
131     }
132     if (!S_ISDIR(ds.st_mode)) {
133     error("imapfilter: file %s not a directory\n", dname);
134     return ERROR_TRIVIAL;
135     }
136     if ((ds.st_mode & 00777) != mode) {
137     error("imapfilter: warning: improper dir %s permissions\n"
138     "imapfilter: warning: file's mode should be %o not %o\n",
139     dname, mode, ds.st_mode & 00777);
140     return ERROR_TRIVIAL;
141     }
142    
143     return 0;
144     }
145     #endif
146 lefcha 1.27
147 lefcha 1.1
148     /*
149 lefcha 1.13 * Find the path to configuration file, open it and call parse_config().
150 lefcha 1.1 */
151     int read_config(char *cfg)
152     {
153     int r;
154     FILE *fp;
155     char *home = NULL;
156 lefcha 1.23 char *c = NULL;
157 lefcha 1.24
158 lefcha 1.1 if (!cfg) {
159 lefcha 1.23 cfg = c = (char *) xmalloc(PATH_MAX * sizeof(char));
160 lefcha 1.8
161 lefcha 1.1 home = getenv("HOME");
162    
163     snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");
164     }
165     #ifdef DEBUG
166 lefcha 1.11 printf("debug: configuration file: '%s'\n", cfg);
167 lefcha 1.1 #endif
168 lefcha 1.13 #ifdef CHECK_PERMISSIONS
169 lefcha 1.28 check_file_perms(cfg, S_IRUSR | S_IWUSR);
170 lefcha 1.12 #endif
171 lefcha 1.1 fp = fopen(cfg, "r");
172    
173 lefcha 1.17 if (!fp)
174     fatal(ERROR_FILE_OPEN, "imapfilter: opening config file %s; %s\n",
175 lefcha 1.11 cfg, strerror(errno));
176 lefcha 1.1
177 lefcha 1.23 if (c)
178     free(c);
179    
180 lefcha 1.17 if ((r = parse_config(fp)))
181     fatal(ERROR_CONFIG_PARSE,
182     "imapfilter: parse error in config file at row %d\n", r);
183 lefcha 1.1
184     fclose(fp);
185    
186 lefcha 1.11 #ifdef DEBUG
187     printf("debug: options: %0#10x\n", options);
188     #endif
189    
190 lefcha 1.17 return 0;
191 lefcha 1.1 }
192    
193 lefcha 1.6
194 lefcha 1.10 /*
195 lefcha 1.13 * Parse configuration file.
196 lefcha 1.1 */
197     int parse_config(FILE * fp)
198     {
199 lefcha 1.17 int i, r = 0;
200 lefcha 1.1 unsigned int row = 0;
201     char line[LINE_MAX];
202 lefcha 1.27 regex_t creg[13];
203 lefcha 1.28 regmatch_t match[8];
204 lefcha 1.27 const char *reg[13] = {
205 lefcha 1.15 "^([[:blank:]]*\n|#.*\n)$",
206 lefcha 1.25 #ifndef SSL_TLS
207 lefcha 1.28 "^[[:blank:]]*ACCOUNT[[:blank:]]+(([[:graph:]]+):([[:graph:]]*)|([[:graph:]]+))@([[:alnum:].-]+)(:[[:digit:]]+)?[[:blank:]]*\n$",
208 lefcha 1.25 #else
209 lefcha 1.28 "^[[:blank:]]*ACCOUNT[[:blank:]]+(([[:graph:]]+):([[:graph:]]*)|([[:graph:]]+))@([[:alnum:].-]+)(:[[:digit:]]+)?[[:blank:]]*([[:blank:]]SSL|[[:blank:]]SSL2|[[:blank:]]SSL3|[[:blank:]]TLS1)?[[:blank:]]*\n$",
210 lefcha 1.25 #endif
211 lefcha 1.13 "^[[:blank:]]*FOLDER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]+([[:graph:]]+)[[:blank:]]*\n$",
212     "^[[:blank:]]*FILTER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]*([[:blank:]]OR|[[:blank:]]AND)?[[:blank:]]*\n$",
213 lefcha 1.17 "^[[:blank:]]*ACTION[[:blank:]]+(DELETE|COPY[[:blank:]]+([[:graph:]]+)|MOVE[[:blank:]]+([[:graph:]]+)|LIST)[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",
214     "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(ANSWERED|DELETED|DRAFT|FLAGGED|NEW|OLD|RECENT|SEEN|UNANSWERED|UNDELETED|UNDRAFT|UNFLAGGED|UNSEEN)[[:blank:]]*\n$",
215     "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(BCC|BODY|CC|FROM|SUBJECT|TEXT|TO)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]*\n$",
216     "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(HEADER)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]*\n$",
217 lefcha 1.26 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(LARGER|SMALLER|OLDER|NEWER)[[:blank:]]+([[:digit:]]+)[[:blank:]]*\n$",
218 lefcha 1.13 "^[[:blank:]]*JOB[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]*\n$",
219 lefcha 1.26 "^[[:blank:]]*(SET[[:blank:]])?[[:blank:]]*(LOGFILE)[[:blank:]]*=[[:blank:]]*([[:print:]]+)\n$",
220 lefcha 1.28 "^[[:blank:]]*(SET[[:blank:]])?[[:blank:]]*(HEADERS|NAMESPACE)[[:blank:]]*=[[:blank:]]*(YES|NO)[[:blank:]]*\n$",
221 lefcha 1.27 "^[[:blank:]]*(SET[[:blank:]])?[[:blank:]]*(TIMEOUT)[[:blank:]]*=[[:blank:]]*(-?[[:digit:]]+)\n$"
222 lefcha 1.1 };
223    
224 lefcha 1.27 for (i = 0; i < 13; i++)
225 lefcha 1.14 regcomp(&creg[i], reg[i], REG_EXTENDED | REG_ICASE);
226 lefcha 1.1
227     while (fgets(line, LINE_MAX - 1, fp)) {
228     row++;
229 lefcha 1.15 if (!regexec(&creg[0], line, 0, match, 0))
230     continue;
231 lefcha 1.26 #ifndef SSL_TLS
232 lefcha 1.28 else if (!regexec(&creg[1], line, 7, match, 0))
233 lefcha 1.25 #else
234 lefcha 1.28 else if (!regexec(&creg[1], line, 8, match, 0))
235 lefcha 1.25 #endif
236 lefcha 1.13 set_account(line, match);
237 lefcha 1.15 else if (!regexec(&creg[2], line, 3, match, 0))
238 lefcha 1.17 r = set_mboxgrp(line, match);
239 lefcha 1.15 else if (!regexec(&creg[3], line, 3, match, 0))
240 lefcha 1.17 r = set_filter(line, match);
241     else if (!regexec(&creg[4], line, 5, match, 0))
242     r = set_action(line, match);
243 lefcha 1.15 else if (!regexec(&creg[5], line, 7, match, 0) ||
244 lefcha 1.18 !regexec(&creg[6], line, 7, match, 0) ||
245     !regexec(&creg[7], line, 7, match, 0) ||
246     !regexec(&creg[8], line, 7, match, 0))
247 lefcha 1.17 r = set_mask(line, match);
248 lefcha 1.15 else if (!regexec(&creg[9], line, 3, match, 0))
249 lefcha 1.17 r = set_job(line, match);
250 lefcha 1.26 else if (!regexec(&creg[10], line, 4, match, 0) ||
251 lefcha 1.27 !regexec(&creg[11], line, 4, match, 0) ||
252     !regexec(&creg[12], line, 4, match, 0))
253 lefcha 1.15 set_options(line, match);
254 lefcha 1.17 else
255 lefcha 1.18 return row;
256    
257 lefcha 1.17 if (r == ERROR_CONFIG_PARSE)
258     return row;
259 lefcha 1.1 }
260 lefcha 1.3
261 lefcha 1.27 for (i = 0; i < 13; i++)
262 lefcha 1.12 regfree(&creg[i]);
263 lefcha 1.18
264 lefcha 1.15 destroy_data();
265 lefcha 1.6
266 lefcha 1.8 return 0;
267 lefcha 1.1 }
268    
269    
270     /*
271 lefcha 1.13 * Set other options found in config file.
272 lefcha 1.11 */
273     void set_options(char *line, regmatch_t * match)
274     {
275 lefcha 1.26 if (!strncasecmp(line + match[2].rm_so, "logfile", 7)) {
276 lefcha 1.19 if (!*logfile)
277 lefcha 1.26 strncat(logfile, line + match[3].rm_so,
278     min((match[3].rm_eo - match[3].rm_so), PATH_MAX - 1));
279 lefcha 1.27 } else if (!strncasecmp(line + match[2].rm_so, "header", 6)) {
280 lefcha 1.26 if (!strncasecmp(line + match[3].rm_so, "yes", 3))
281 lefcha 1.19 options |= OPTION_HEADERS;
282 lefcha 1.25 else
283     options &= ~(OPTION_HEADERS);
284 lefcha 1.28 } else if (!strncasecmp(line + match[2].rm_so, "namespace", 9)) {
285     if (!strncasecmp(line + match[3].rm_so, "yes", 3))
286     options |= OPTION_NAMESPACE;
287     else
288     options &= ~(OPTION_NAMESPACE);
289 lefcha 1.27 } else if (!strncasecmp(line + match[2].rm_so, "timeout", 7)) {
290     errno = 0;
291     timeout = strtol(line + match[3].rm_so, NULL, 10);
292     if (errno)
293     timeout = 0;
294 lefcha 1.19 }
295 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26