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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.26.2.1 - (show annotations)
Wed Dec 5 09:57:38 2001 UTC (22 years, 3 months ago) by lefcha
Branch: release-0_7-patches
Changes since 1.26: +21 -7 lines
File MIME type: text/plain
Timeout and namespace changes.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26