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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.25 - (show annotations)
Wed Oct 17 14:06:20 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
Changes since 1.24: +10 -2 lines
File MIME type: text/plain
Added SSL/TLS support.

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 #include <sys/stat.h>
9
10 #include "config.h"
11 #include "imapfilter.h"
12 #include "data.h"
13
14
15 extern char logfile[PATH_MAX];
16 extern unsigned int options;
17
18
19 /*
20 * Find the path to configuration file, open it and call parse_config().
21 */
22 int read_config(char *cfg)
23 {
24 int r;
25 FILE *fp;
26 char *home = NULL;
27 char *c = NULL;
28
29 if (!cfg) {
30 cfg = c = (char *) xmalloc(PATH_MAX * sizeof(char));
31
32 home = getenv("HOME");
33
34 snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");
35 }
36 #ifdef DEBUG
37 printf("debug: configuration file: '%s'\n", cfg);
38 #endif
39 #ifdef CHECK_PERMISSIONS
40 check_permissions(cfg);
41 #endif
42 fp = fopen(cfg, "r");
43
44 if (!fp)
45 fatal(ERROR_FILE_OPEN, "imapfilter: opening config file %s; %s\n",
46 cfg, strerror(errno));
47
48 if (c)
49 free(c);
50
51 if ((r = parse_config(fp)))
52 fatal(ERROR_CONFIG_PARSE,
53 "imapfilter: parse error in config file at row %d\n", r);
54
55 fclose(fp);
56
57 #ifdef DEBUG
58 printf("debug: options: %0#10x\n", options);
59 #endif
60
61 return 0;
62 }
63
64
65 #ifdef CHECK_PERMISSIONS
66 /*
67 * Check the permissions of the configuration file.
68 */
69 int check_permissions(char *cfg)
70 {
71 struct stat fs;
72
73 if (stat(cfg, &fs)) {
74 error("imapfilter: getting file %s status; %s\n", cfg,
75 strerror(errno));
76 return ERROR_TRIVIAL;
77 }
78 if (!S_ISREG(fs.st_mode)) {
79 error("imapfilter: file %s not a regular file\n", cfg);
80 return ERROR_TRIVIAL;
81 }
82 if ((fs.st_mode & 00777) != (S_IRUSR | S_IWUSR)) {
83 error("imapfilter: warning: improper config file %s permissions\n"
84 "imapfilter: warning: file's mode should be 600 not %o\n",
85 cfg, fs.st_mode & 00777);
86 return ERROR_TRIVIAL;
87 }
88 return 0;
89 }
90 #endif
91
92 /*
93 * Parse configuration file.
94 */
95 int parse_config(FILE * fp)
96 {
97 int i, r = 0;
98 unsigned int row = 0;
99 char line[LINE_MAX];
100 regex_t creg[12];
101 regmatch_t match[7];
102 const char *reg[12] = {
103 "^([[:blank:]]*\n|#.*\n)$",
104 #ifndef SSL_TLS
105 "^[[:blank:]]*ACCOUNT[[:blank:]]+([[:graph:]]*):([[:graph:]]*)@([[:alnum:].-]+)(:[[:digit:]]+)?[[:blank:]]*\n$",
106 #else
107 "^[[:blank:]]*ACCOUNT[[:blank:]]+([[:graph:]]*):([[:graph:]]*)@([[:alnum:].-]+)(:[[:digit:]]+)?[[:blank:]]*([[:blank:]]SSL|[[:blank:]]SSL2|[[:blank:]]SSL3|[[:blank:]]TLS1)?[[:blank:]]*\n$",
108 #endif
109 "^[[:blank:]]*FOLDER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]+([[:graph:]]+)[[:blank:]]*\n$",
110 "^[[:blank:]]*FILTER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]*([[:blank:]]OR|[[:blank:]]AND)?[[:blank:]]*\n$",
111 "^[[:blank:]]*ACTION[[:blank:]]+(DELETE|COPY[[:blank:]]+([[:graph:]]+)|MOVE[[:blank:]]+([[:graph:]]+)|LIST)[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",
112 "^[[: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$",
113 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(BCC|BODY|CC|FROM|SUBJECT|TEXT|TO)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]*\n$",
114 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(HEADER)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]+(\"[[:print:]]*\"|[[:graph:]]+)[[:blank:]]*\n$",
115 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(LARGER|SMALLER)[[:blank:]]+([[:digit:]]+)[[:blank:]]*\n$",
116 "^[[:blank:]]*JOB[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]*\n$",
117 "^[[:blank:]]*(LOGFILE)[[:blank:]]*=[[:blank:]]*([[:print:]]+)\n$",
118 "^[[:blank:]]*(HEADERS)[[:blank:]]*=[[:blank:]]*(YES|NO)[[:blank:]]*\n$"
119 };
120
121 for (i = 0; i < 12; i++)
122 regcomp(&creg[i], reg[i], REG_EXTENDED | REG_ICASE);
123
124 while (fgets(line, LINE_MAX - 1, fp)) {
125 row++;
126 if (!regexec(&creg[0], line, 0, match, 0))
127 continue;
128 #ifndef SSL_TLS
129 else if (!regexec(&creg[1], line, 5, match, 0))
130 #else
131 else if (!regexec(&creg[1], line, 6, match, 0))
132 #endif
133 set_account(line, match);
134 else if (!regexec(&creg[2], line, 3, match, 0))
135 r = set_mboxgrp(line, match);
136 else if (!regexec(&creg[3], line, 3, match, 0))
137 r = set_filter(line, match);
138 else if (!regexec(&creg[4], line, 5, match, 0))
139 r = set_action(line, match);
140 else if (!regexec(&creg[5], line, 7, match, 0) ||
141 !regexec(&creg[6], line, 7, match, 0) ||
142 !regexec(&creg[7], line, 7, match, 0) ||
143 !regexec(&creg[8], line, 7, match, 0))
144 r = set_mask(line, match);
145 else if (!regexec(&creg[9], line, 3, match, 0))
146 r = set_job(line, match);
147 else if (!regexec(&creg[10], line, 3, match, 0) ||
148 !regexec(&creg[11], line, 3, match, 0))
149 set_options(line, match);
150 else
151 return row;
152
153 if (r == ERROR_CONFIG_PARSE)
154 return row;
155 }
156
157 for (i = 0; i < 12; i++)
158 regfree(&creg[i]);
159
160 destroy_data();
161
162 return 0;
163 }
164
165
166 /*
167 * Set other options found in config file.
168 */
169 void set_options(char *line, regmatch_t * match)
170 {
171 if (!strncasecmp(line + match[1].rm_so, "logfile", 7)) {
172 if (!*logfile)
173 strncat(logfile, line + match[2].rm_so,
174 min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1));
175 } else {
176 if (!strncasecmp(line + match[2].rm_so, "yes", 3))
177 options |= OPTION_HEADERS;
178 else
179 options &= ~(OPTION_HEADERS);
180 }
181 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26