paths.h may not be available elsewhere
[infodrom/newmail] / folder.c
1 /*
2     Copyright (c) 2004  Joey Schulze <joey@infodrom.org>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <strings.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <pwd.h>
27 #include <errno.h>
28 #ifdef linux
29 #include <paths.h>
30 #else
31 #define _PATH_MAILDIR "/var/spool/mail"
32 #endif
33 #include "mbox.h"
34 #include "optdefs.h"
35
36 #define FOLDERS_DELTA   5
37
38 struct folder {
39   char *path;
40   char *prefix;
41   off_t size;
42 };
43
44 struct folder **folders = NULL;
45 unsigned int numfolders = 0;
46 unsigned int maxfolders = 0;
47
48 void add_folder(char *path)
49 {
50   struct folder *thisfolder;
51   struct stat st;
52   char *cp;
53   int sh;
54
55   if (numfolders == maxfolders) {
56     if ((folders = (struct folder **)
57          realloc(folders,
58                  (maxfolders + FOLDERS_DELTA) * sizeof(struct folder *))) == NULL) {
59       perror("realloc");
60       exit(1);
61     }
62     maxfolders += FOLDERS_DELTA;
63   }
64
65   if ((thisfolder = (struct folder *)malloc(sizeof(struct folder))) == NULL) {
66     perror ("malloc");
67     exit (1);
68   }
69
70   if ((cp = index(path, '=')) != NULL) {
71     *cp++ = '\0';
72     if ((thisfolder->prefix = (char *)strdup(cp)) == NULL) {
73       perror ("strdup");
74       exit (1);
75     }
76     strcpy(thisfolder->prefix, cp);
77   } else {
78     if (numfolders > 0) {
79       /* More than one mailbox to monitor --> need prefix anyway */
80       if ((cp = rindex(path, '/')) != NULL) {
81         cp++;
82         if ((thisfolder->prefix = (char *)strdup(cp)) == NULL) {
83           perror ("strdup");
84           exit (1);
85         }
86       } else {
87         if ((thisfolder->prefix = (char *)strdup(path)) == NULL) {
88           perror ("strdup");
89           exit (1);
90         }
91       }
92     } else
93       thisfolder->prefix = NULL;
94   }
95
96   if ((thisfolder->path = (char *)strdup(path)) == NULL) {
97     perror ("strdup");
98     exit (1);
99   }
100
101   sh = stat(path, &st);
102
103   if (sh == 0) {
104     thisfolder->size = st.st_size;
105   } else if (sh == -1 && errno == ENOENT) {
106     thisfolder->size = 0;
107   } else {
108     free (thisfolder->path);
109     free (thisfolder);
110     return;
111   }
112
113   folders[numfolders++] = thisfolder;
114 }
115
116 void add_default_folder()
117 {
118   char path[128];
119   char *env;
120   uid_t uid;
121   struct passwd *pw;
122
123   if ((env = getenv("MAIL")) == NULL) {
124     uid = getuid();
125     if ((pw = getpwuid(uid)) == NULL) {
126       perror ("getpwuid");
127       exit (1);
128     }
129
130     snprintf (path, sizeof(path), "%s/%s", _PATH_MAILDIR, pw->pw_name);
131   } else {
132     snprintf (path, sizeof(path), env);
133   }
134
135   add_folder(path);
136 }
137
138 void fix_prefix()
139 {
140   char *cp;
141
142   if (numfolders < 2)
143     return;
144
145   if (folders[0]->prefix != NULL)
146     return;
147
148   if ((cp = rindex(folders[0]->path, '/')) != NULL) {
149     cp++;
150     if ((folders[0]->prefix = (char *)strdup(cp)) == NULL) {
151       perror ("strdup");
152       exit (1);
153     }
154   } else {
155     if ((folders[0]->prefix = (char *)strdup(folders[0]->path)) == NULL) {
156       perror ("strdup");
157       exit (1);
158     }
159   }
160 }
161
162 void watch_folders(int opt_flags)
163 {
164   unsigned int i;
165   int newmail = 0;
166
167   for (i=0; i < numfolders; i++)
168     newmail |= watch_mbox(folders[i]->path, folders[i]->prefix, &folders[i]->size, opt_flags);
169
170   if (newmail) {
171     if (!(opt_flags & OPT_WINDOW)) {
172       if (opt_flags & OPT_BELL)
173         putchar ('\007');
174       putchar ('\n');
175     }
176     fflush (stdout);
177   }
178 }