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

Contents of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Mon Sep 10 23:43:29 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.12: +41 -247 lines
File MIME type: text/plain
New imapfilter.

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
28 if (!cfg) {
29 cfg = (char *) malloc(PATH_MAX * sizeof(char));
30
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 error("imapfilter: opening config file %s; %s\n",
46 cfg, strerror(errno));
47 return 1;
48 }
49
50 r = parse_config(fp);
51
52 fclose(fp);
53
54 #ifdef DEBUG
55 printf("debug: options: %0#10x\n", options);
56 #endif
57
58 return r;
59 }
60
61
62 #ifdef CHECK_PERMISSIONS
63 /*
64 * Check the permissions of the configuration file.
65 */
66 int check_permissions(char *cfg)
67 {
68 struct stat fs;
69
70 if (stat(cfg, &fs)) {
71 error("imapfilter: getting file %s status; %s\n", cfg,
72 strerror(errno));
73 return 1;
74 }
75
76 if (!S_ISREG(fs.st_mode)) {
77 error("imapfilter: file %s not a regular file\n", cfg);
78 return 1;
79 }
80
81 if ((fs.st_mode & 00777) != (S_IRUSR | S_IWUSR)) {
82 fprintf(stderr,
83 "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 1;
87 }
88
89 return 0;
90 }
91 #endif
92
93 /*
94 * Parse configuration file.
95 */
96 int parse_config(FILE * fp)
97 {
98 int i;
99 unsigned int row = 0;
100 char line[LINE_MAX];
101 regex_t creg[10];
102 regmatch_t match[7];
103 const char *reg[10] = {
104 "^[[:blank:]]*ACCOUNT[[:blank:]]+([[:graph:]]*):([[:graph:]]*)@([[:alnum:].-]+):?([[:digit:]]{0,5})[[:blank:]]*\n$",
105 "^[[:blank:]]*FOLDER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]+([[:graph:]]+)[[:blank:]]*\n$",
106 "^[[:blank:]]*FILTER[[:blank:]]+([[:alnum:]_-]+)[[:blank:]]*([[:blank:]]OR|[[:blank:]]AND)?[[:blank:]]*\n$",
107 "^[[:blank:]]*ACTION[[:blank:]]+(DELETE|COPY|MOVE|LIST)[[:blank:]]*([[:graph:]]*)[[:blank:]]*\n$",
108 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(ALL|ANSWERED|DELETED|DRAFT|FLAGGED|NEW|OLD|RECENT|SEEN|UNANSWERED|UNDELETED|UNDRAFT|UNFLAGGED|UNSEEN)[[:blank:]]*\n$",
109 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(BCC|BODY|CC|FROM|SUBJECT|TEXT|TO)[[:blank:]]+([[:print:]]+)\n$",
110 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(HEADER)[[:blank:]]+([[:graph:]]+)[[:blank:]]+([[:print:]]+)\n$",
111 "^[[:blank:]]*(MASK[[:blank:]])?[[:blank:]]*(OR[[:blank:]]|AND[[:blank:]])?[[:blank:]]*(NOT[[:blank:]])?[[:blank:]]*(LARGER|SMALLER)[[:blank:]]+([[:digit:]]+)[[:blank:]]*\n$",
112 "^[[:blank:]]*JOB[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]+([[:alnum:],_-]+)[[:blank:]]*\n$",
113 "^([[:blank:]]*\n|#.*\n)$"
114 };
115
116 for (i = 0; i < 10; i++)
117 regcomp(&creg[i], reg[i], REG_EXTENDED);
118
119 while (fgets(line, LINE_MAX - 1, fp)) {
120 row++;
121 if (!regexec(&creg[0], line, 6, match, 0)) {
122 set_account(line, match);
123 continue;
124 } else if (!regexec(&creg[1], line, 3, match, 0)) {
125 set_mboxgrp(line, match);
126 continue;
127 } else if (!regexec(&creg[2], line, 3, match, 0)) {
128 set_filter(line, match);
129 continue;
130 } else if (!regexec(&creg[3], line, 3, match, 0)) {
131 set_action(line, match);
132 continue;
133 } else if (!regexec(&creg[4], line, 7, match, 0) ||
134 !regexec(&creg[5], line, 7, match, 0) ||
135 !regexec(&creg[6], line, 7, match, 0) ||
136 !regexec(&creg[7], line, 7, match, 0)) {
137 set_mask(line, match);
138 continue;
139 } else if (!regexec(&creg[8], line, 3, match, 0)) {
140 set_job(line, match);
141 continue;
142 } else if (!regexec(&creg[9], line, 0, match, 0)) {
143 continue;
144 } else {
145 error("imapfilter: parse error in config file at row %d\n",
146 row);
147 return 1;
148 }
149 }
150
151 for (i = 0; i < 10; i++)
152 regfree(&creg[i]);
153
154 return 0;
155 }
156
157
158 /*
159 * Set other options found in config file.
160 */
161 void set_options(char *line, regmatch_t * match)
162 {
163 int s;
164
165 if (!*logfile && !strncmp(line + match[1].rm_so, "LOGFILE", 7)) {
166 s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);
167 strncpy(logfile, line + match[2].rm_so, s);
168 logfile[s] = 0;
169 }
170 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26