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

Diff of /imapfilter/file.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by lefcha, Sat Aug 11 15:52:52 2001 UTC revision 1.63 by lefcha, Fri Feb 13 12:17:15 2004 UTC
# Line 1  Line 1 
1  #include <stdio.h>  #include <stdio.h>
2  #include <errno.h>  #include <unistd.h>
 #include <regex.h>  
3  #include <string.h>  #include <string.h>
4  #include <stdlib.h>  #include <errno.h>
5  #include <limits.h>  #include <limits.h>
6    #include <sys/types.h>
7    #include <sys/stat.h>
8    #include <fcntl.h>
9    
10  #include "config.h"  #include "config.h"
11  #include "imapfilter.h"  #include "imapfilter.h"
12  #include "file.h"  #include "pathnames.h"
13  #include "log.h"  
14    
15    extern char *home;
16    extern options_t opts;
17    
18    
19    /*
20     * Create imapfilter's home directory.
21     */
22    int
23    create_homedir(void)
24    {
25            char hd[PATH_MAX];
26    
27            snprintf(hd, PATH_MAX, "%s/%s", home, PATHNAME_HOME);
28    
29            if (!exists_dir(hd)) {
30                    if (mkdir(hd, S_IRUSR | S_IWUSR | S_IXUSR))
31                            error("could not create directory %s; %s\n", hd,
32                                strerror(errno));
33            } else {
34                    check_dir_perms(hd, S_IRUSR | S_IWUSR | S_IXUSR);
35            }
36            return 0;
37    }
38    
39    
40    /*
41     * Check if a file exists.
42     */
43    int
44    exists_file(char *fname)
45    {
46            struct stat fs;
47    
48            if (access(fname, F_OK))
49                    return 0;
50    
51            stat(fname, &fs);
52            if (!S_ISREG(fs.st_mode)) {
53                    error("file %s not a regular file\n", fname);
54                    return ERROR_FILEOPEN;
55            }
56            return 1;
57    }
58    
59    
60    /*
61     * Check if a directory exists.
62     */
63    int
64    exists_dir(char *dname)
65    {
66            struct stat ds;
67    
68            if (access(dname, F_OK))
69                    return 0;
70    
71            stat(dname, &ds);
72            if (!S_ISDIR(ds.st_mode)) {
73                    error("file %s not a directory\n", dname);
74                    return ERROR_FILEOPEN;
75            }
76            return 1;
77    }
78    
79    
80    /*
81     * Create a file with the specified permissions.
82     */
83    int
84    create_file(char *fname, mode_t mode)
85    {
86            int fd;
87    
88            fd = 0;
89    
90            if (!exists_file(fname)) {
91                    fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, mode);
92                    if (fd == -1) {
93                            error("could not create file %s; %s\n", fname,
94                                strerror(errno));
95                            return ERROR_FILEOPEN;
96                    }
97                    close(fd);
98            }
99            return 0;
100    }
101    
102    
103    /*
104     * Check the permissions of a file.
105     */
106    int
107    check_file_perms(char *fname, mode_t mode)
108    {
109            struct stat fs;
110    
111  account_data account;          if (opts.verbosity <= -1)
112  filter_entry **filters;                  return 0;
 int fcnt = 0;                   /* Counter of how many filters were  
                                    found in configuration file. */  
   
   
 /*  
  * Finds path to configuration file, opens it and calls parse_config().  
  */  
 int read_config(char *cfg)  
 {  
     int r;  
     FILE *fp;  
     char *home = NULL;  
   
     if (!cfg) {  
         cfg = (char *) malloc(PATH_MAX * sizeof(char));  
   
         home = getenv("HOME");  
   
         snprintf(cfg, PATH_MAX, "%s/%s", home, ".imapfilterrc");  
     }  
 #ifdef DEBUG  
     printf("debug: configuration file: %s\n", cfg);  
 #endif  
   
     fp = fopen(cfg, "r");  
   
     if (!fp) {  
         fprintf(stderr, "imapfilter: Could not open config file %s; %s\n",  
                 cfg, strerror(errno));  
         return FAILURE;  
     }  
   
     account.port = 143;         /* Default IMAP protocol port to connect. */  
   
     r = parse_config(fp);  
   
     fclose(fp);  
   
     return r;  
 }  
   
 /*  
  * Parses configuration file.  
  */  
 int parse_config(FILE * fp)  
 {  
     int i;  
     unsigned int row = 0;  
     char line[LINE_MAX];  
     regex_t comreg[4];  
     regmatch_t match[3];  
     const char *reg[] = {  
         "^[[:blank:]]*(SERVER|PORT|USERNAME|PASSWORD|LOGFILE)[[:blank:]]*=[[:blank:]]*([[:graph:]]*)[[:blank:]]*",  
         "^[[:blank:]]*DENY[[:blank:]]*=[[:blank:]]*(FROM|CC|BCC|SUBJECT|TO):? ([[:print:]]*)",  
         "^[[:blank:]]*DENY[[:blank:]]*=[[:blank:]]*([[:graph:]]+):? ([[:print:]]*)",  
         "^[[:blank:]]*#{0,1}.*"  
     };  
   
     for (i = 0; i < 4; i++)  
         regcomp(&comreg[i], reg[i], REG_EXTENDED);  
   
     while (fgets(line, LINE_MAX - 1, fp)) {  
         row++;  
         if (!regexec(&comreg[0], line, 3, match, 0)) {  
             set_account(line, match);  
             continue;  
         } else if (!regexec(&comreg[1], line, 3, match, 0)) {  
             standard_filter(line, match);  
             continue;  
         } else if (!regexec(&comreg[2], line, 3, match, 0)) {  
             explicit_filter(line, match);  
             continue;  
         } else if (!regexec(&comreg[3], line, 1, match, 0))  
             continue;  
         else {  
             fprintf(stderr,  
                     "imapfilter: parse error in config file at row %d\n",  
                     row);  
             return FAILURE;  
         }  
     }  
 #ifdef DEBUG  
     printf("debug: account setting SERVER: '%s'\n"  
            "debug: account setting PORT: %d\n"  
            "debug: account setting USERNAME: '%s'\n"  
            "debug: account setting PASSWORD: '%s'\n"  
            "debug: account setting LOGFILE: '%s'\n",  
            account.server, account.port, account.username,  
            account.password, account.logfile);  
 #endif  
     return SUCCESS;  
 }  
   
   
 /*  
  * An account setting was found from parse_config(), changes the  
  * apropriate variable.  
  */  
 void set_account(char *line, regmatch_t * match)  
 {  
     int s;  
     char port[6];  
   
     if (!strncmp(line + match[1].rm_so, "SERVER", 6)) {  
         s = min((match[2].rm_eo - match[2].rm_so), SERVER_MAX - 1);  
         strncpy(account.server, line + match[2].rm_so, s);  
         account.server[s] = 0;  
     } else if (!strncmp(line + match[1].rm_so, "PORT", 4)) {  
         strncpy(port, line + match[2].rm_so,  
                 min((match[2].rm_eo - match[2].rm_so), sizeof(port)));  
         account.port = strtoul(port, NULL, 0);  
     } else if (!strncmp(line + match[1].rm_so, "USERNAME", 8)) {  
         s = min((match[2].rm_eo - match[2].rm_so), USERNAME_MAX - 1);  
         strncpy(account.username, line + match[2].rm_so, s);  
         account.username[s] = 0;  
     } else if (!strncmp(line + match[1].rm_so, "PASSWORD", 8)) {  
         s = min((match[2].rm_eo - match[2].rm_so), PASSWORD_MAX - 1);  
         strncpy(account.password, line + match[2].rm_so, s);  
         account.password[s] = 0;  
     } else if (!strncmp(line + match[1].rm_so, "LOGFILE", 7)) {  
         s = min((match[2].rm_eo - match[2].rm_so), PATH_MAX - 1);  
         strncpy(account.logfile, line + match[2].rm_so, s);  
         account.logfile[s] = 0;  
     }  
 }  
   
   
 /*  
  * A filter entry was found from parse_config() proccesses it and saves it.  
  */  
 void set_filters(char *line, regmatch_t * match, int expl)  
 {  
     int s;  
   
     /* Every FILTER_ENTRIES_MAX, space for more filters is realloc() -ed. */  
     if (!fcnt)  
         filters =  
             (filter_entry **) malloc(FILTER_ENTRIES_MAX *  
                                     sizeof(filter_entry *));  
     else if (!(fcnt % FILTER_ENTRIES_MAX))  
         filters = (filter_entry **) realloc(filters,  
                                            (((fcnt / FILTER_ENTRIES_MAX) +  
                                              1) * FILTER_ENTRIES_MAX) *  
                                            sizeof(filter_entry *));  
       
     filters[fcnt] = (filter_entry *) malloc(sizeof(filter_entry));  
   
     filters[fcnt]->explicit = expl;  
       
     s = min((match[1].rm_eo - match[1].rm_so), FIELD_NAME_MAX - 1);  
     strncpy(filters[fcnt]->name, line + match[1].rm_so, s);  
     filters[fcnt]->name[s] = 0;  
   
     s = min((match[2].rm_eo - match[2].rm_so), FIELD_BODY_MAX - 1);  
     strncpy(filters[fcnt]->body, line + match[2].rm_so, s);  
     filters[fcnt]->body[s] = 0;  
   
 #ifdef DEBUG  
     printf("debug: filter entry '%s': '%s'\n", filters[fcnt]->name,  
            filters[fcnt]->body);  
 #endif  
113    
114      fcnt++;          if (stat(fname, &fs)) {
115                    error("getting file %s status; %s\n", fname,
116                        strerror(errno));
117                    return ERROR_TRIVIAL;
118            }
119            if (!S_ISREG(fs.st_mode)) {
120                    error("file %s not a regular file\n", fname);
121                    return ERROR_TRIVIAL;
122            }
123            if ((fs.st_mode & 00777) != mode) {
124                    error("warning: file's %s mode should be %o not %o\n", fname,
125                        mode, fs.st_mode & 00777);
126                    return ERROR_TRIVIAL;
127            }
128            return 0;
129    }
130    
131    
132    /*
133     * Check the permissions of a directory.
134     */
135    int
136    check_dir_perms(char *dname, mode_t mode)
137    {
138            struct stat ds;
139    
140            if (opts.verbosity <= -1)
141                    return 0;
142    
143            if (stat(dname, &ds)) {
144                    error("getting file %s status; %s\n", dname,
145                        strerror(errno));
146                    return ERROR_TRIVIAL;
147            }
148            if (!S_ISDIR(ds.st_mode)) {
149                    error("file %s not a directory\n", dname);
150                    return ERROR_TRIVIAL;
151            }
152            if ((ds.st_mode & 00777) != mode) {
153                    error("warning: dir's %s mode should be %o not %o\n", dname,
154                        mode, ds.st_mode & 00777);
155                    return ERROR_TRIVIAL;
156            }
157            return 0;
158  }  }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.63

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26