Added installation blurb
[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 #include <paths.h>
29 #include "mbox.h"
30 #include "optdefs.h"
31
32 #define FOLDERS_DELTA   5
33
34 struct folder {
35   char *path;
36   char *prefix;
37   off_t size;
38 };
39
40 struct folder **folders = NULL;
41 unsigned int numfolders = 0;
42 unsigned int maxfolders = 0;
43
44 void add_folder(char *path)
45 {
46   struct folder *thisfolder;
47   struct stat st;
48   char *cp;
49   int sh;
50
51   if (numfolders == maxfolders) {
52     if ((folders = (struct folder **)
53          realloc(folders,
54                  (maxfolders + FOLDERS_DELTA) * sizeof(struct folder *))) == NULL) {
55       perror("realloc");
56       exit(1);
57     }
58     maxfolders += FOLDERS_DELTA;
59   }
60
61   if ((thisfolder = (struct folder *)malloc(sizeof(struct folder))) == NULL) {
62     perror ("malloc");
63     exit (1);
64   }
65
66   if ((cp = index(path, '=')) != NULL) {
67     *cp++ = '\0';
68     if ((thisfolder->prefix = (char *)strdup(cp)) == NULL) {
69       perror ("strdup");
70       exit (1);
71     }
72     strcpy(thisfolder->prefix, cp);
73   } else {
74     if (numfolders > 0) {
75       /* More than one mailbox to monitor --> need prefix anyway */
76       if ((cp = rindex(path, '/')) != NULL) {
77         cp++;
78         if ((thisfolder->prefix = (char *)strdup(cp)) == NULL) {
79           perror ("strdup");
80           exit (1);
81         }
82       } else {
83         if ((thisfolder->prefix = (char *)strdup(path)) == NULL) {
84           perror ("strdup");
85           exit (1);
86         }
87       }
88     } else
89       thisfolder->prefix = NULL;
90   }
91
92   if ((thisfolder->path = (char *)strdup(path)) == NULL) {
93     perror ("strdup");
94     exit (1);
95   }
96
97   sh = stat(path, &st);
98
99   if (sh == 0) {
100     thisfolder->size = st.st_size;
101   } else if (sh == -1 && errno == ENOENT) {
102     thisfolder->size = 0;
103   } else {
104     free (thisfolder->path);
105     free (thisfolder);
106     return;
107   }
108
109   folders[numfolders++] = thisfolder;
110 }
111
112 void add_default_folder()
113 {
114   char path[128];
115   char *env;
116   uid_t uid;
117   struct passwd *pw;
118
119   if ((env = getenv("MAIL")) == NULL) {
120     uid = getuid();
121     if ((pw = getpwuid(uid)) == NULL) {
122       perror ("getpwuid");
123       exit (1);
124     }
125
126     snprintf (path, sizeof(path), "%s/%s", _PATH_MAILDIR, pw->pw_name);
127   } else {
128     snprintf (path, sizeof(path), env);
129   }
130
131   add_folder(path);
132 }
133
134 void fix_prefix()
135 {
136   char *cp;
137
138   if (numfolders < 2)
139     return;
140
141   if (folders[0]->prefix != NULL)
142     return;
143
144   if ((cp = rindex(folders[0]->path, '/')) != NULL) {
145     cp++;
146     if ((folders[0]->prefix = (char *)strdup(cp)) == NULL) {
147       perror ("strdup");
148       exit (1);
149     }
150   } else {
151     if ((folders[0]->prefix = (char *)strdup(folders[0]->path)) == NULL) {
152       perror ("strdup");
153       exit (1);
154     }
155   }
156 }
157
158 void watch_folders(int opt_flags)
159 {
160   unsigned int i;
161   int newmail = 0;
162
163   for (i=0; i < numfolders; i++)
164     newmail |= watch_mbox(folders[i]->path, folders[i]->prefix, &folders[i]->size, opt_flags);
165
166   if (newmail) {
167     if (!(opt_flags & OPT_WINDOW)) {
168       if (opt_flags & OPT_BELL)
169         putchar ('\007');
170       putchar ('\n');
171     }
172     fflush (stdout);
173   }
174 }