sort includes and remove two bogus whitelines.
[monky] / src / mail.c
1 /*
2  * Conky, a system monitor, based on torsmo
3  *
4  * This program is licensed under BSD license, read COPYING
5  *
6  *  $Id$
7  */
8
9 #include <sys/stat.h>
10 #include <sys/time.h>
11
12 #include <dirent.h>
13 #include <errno.h>
14 #include <stdio.h>
15 #include <string.h>
16
17 #include "conky.h"
18
19 char *current_mail_spool;
20
21 static time_t last_mail_mtime;
22 static double last_mail_update;
23
24 void update_mail_count()
25 {
26         struct stat buf;
27
28         if (current_mail_spool == NULL)
29                 return;
30
31         /* TODO: use that fine file modification notify on Linux 2.4 */
32
33         /* don't check mail so often (9.5s is minimum interval) */
34         if (current_update_time - last_mail_update < 9.5)
35                 return;
36         else
37                 last_mail_update = current_update_time;
38
39         if (stat(current_mail_spool, &buf)) {
40                 static int rep;
41                 if (!rep) {
42                         ERR("can't stat %s: %s", current_mail_spool,
43                             strerror(errno));
44                         rep = 1;
45                 }
46                 return;
47         }
48 #if HAVE_DIRENT_H
49         /* maildir format */
50         if (S_ISDIR(buf.st_mode)) {
51                 DIR *dir;
52                 char *dirname;
53                 struct dirent *dirent;
54                 info.mail_count = 0;
55                 info.new_mail_count = 0;
56
57                 dirname =
58                     (char *) malloc(sizeof(char) *
59                                     (strlen(current_mail_spool) + 5));
60                 if (!dirname) {
61                         ERR("malloc");
62                         return;
63                 }
64                 strcpy(dirname, current_mail_spool);
65                 strcat(dirname, "/");
66                 /* checking the cur subdirectory */
67                 strcat(dirname, "cur");
68
69                 dir = opendir(dirname);
70                 if (!dir) {
71                         ERR("cannot open directory");
72                         free(dirname);
73                         return;
74                 }
75                 dirent = readdir(dir);
76                 while (dirent) {
77                         /* . and .. are skipped */
78                         if (dirent->d_name[0] != '.') {
79                                 info.mail_count++;
80                         }
81                         dirent = readdir(dir);
82                 }
83                 closedir(dir);
84
85                 dirname[strlen(dirname) - 3] = '\0';
86                 strcat(dirname, "new");
87
88                 dir = opendir(dirname);
89                 if (!dir) {
90                         ERR("cannot open directory");
91                         free(dirname);
92                         return;
93                 }
94                 dirent = readdir(dir);
95                 while (dirent) {
96                         /* . and .. are skipped */
97                         if (dirent->d_name[0] != '.') {
98                                 info.new_mail_count++;
99                                 info.mail_count++;
100                         }
101                         dirent = readdir(dir);
102                 }
103                 closedir(dir);
104
105                 free(dirname);
106                 return;
107         }
108 #endif
109         /* mbox format */
110         if (buf.st_mtime != last_mail_mtime) {
111                 /* yippee, modification time has changed, let's read mail count! */
112                 static int rep;
113                 FILE *fp;
114                 int reading_status = 0;
115
116                 /* could lock here but I don't think it's really worth it because
117                  * this isn't going to write mail spool */
118
119                 info.new_mail_count = 0;
120                 info.mail_count = 0;
121
122                 fp = open_file(current_mail_spool, &rep);
123                 if (!fp)
124                         return;
125
126                 /* NOTE: adds mail as new if there isn't Status-field at all */
127
128                 while (!feof(fp)) {
129                         char buf[128];
130                         if (fgets(buf, 128, fp) == NULL)
131                                 break;
132
133                         if (strncmp(buf, "From ", 5) == 0) {
134                                 /* ignore MAILER-DAEMON */
135                                 if (strncmp(buf + 5, "MAILER-DAEMON ", 14)
136                                     != 0) {
137                                         info.mail_count++;
138
139                                         if (reading_status)
140                                                 info.new_mail_count++;
141                                         else
142                                                 reading_status = 1;
143                                 }
144                         } else {
145                                 if (reading_status
146                                     && strncmp(buf, "X-Mozilla-Status:",
147                                                17) == 0) {
148                                         /* check that mail isn't already read */
149                                         if (strchr(buf + 21, '0'))
150                                                 info.new_mail_count++;
151
152                                         reading_status = 0;
153                                         continue;
154                                 }
155                                 if (reading_status
156                                     && strncmp(buf, "Status:", 7) == 0) {
157                                         /* check that mail isn't already read */
158                                         if (strchr(buf + 7, 'R') == NULL)
159                                                 info.new_mail_count++;
160
161                                         reading_status = 0;
162                                         continue;
163                                 }
164                         }
165
166                         /* skip until \n */
167                         while (strchr(buf, '\n') == NULL && !feof(fp))
168                                 fgets(buf, 128, fp);
169                 }
170
171                 fclose(fp);
172
173                 if (reading_status)
174                         info.new_mail_count++;
175
176                 last_mail_mtime = buf.st_mtime;
177         }
178 }