Reformatted all code
[monky] / src / mail.c
1 /* Conky, a system monitor, based on torsmo
2  *
3  * Any original torsmo code is licensed under the BSD license
4  *
5  * All code written since the fork of torsmo is licensed under the GPL
6  *
7  * Please see COPYING for details
8  *
9  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
10  * Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
11  *      (see AUTHORS)
12  * All rights reserved.
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  *
26  * $Id$ */
27
28 #include <sys/stat.h>
29 #include <sys/time.h>
30
31 #include <dirent.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "conky.h"
37
38 char *current_mail_spool;
39
40 void update_mail_count(struct local_mail_s *mail)
41 {
42         struct stat buf;
43
44         if (mail == NULL) {
45                 return;
46         }
47
48         /* TODO: use that fine file modification notify on Linux 2.4 */
49
50         /* don't check mail so often (9.5s is minimum interval) */
51         if (current_update_time - mail->last_update < 9.5) {
52                 return;
53         } else {
54                 mail->last_update = current_update_time;
55         }
56
57         if (stat(mail->box, &buf)) {
58                 static int rep;
59
60                 if (!rep) {
61                         ERR("can't stat %s: %s", mail->box, strerror(errno));
62                         rep = 1;
63                 }
64                 return;
65         }
66 #if HAVE_DIRENT_H
67         /* maildir format */
68         if (S_ISDIR(buf.st_mode)) {
69                 DIR *dir;
70                 char *dirname;
71                 struct dirent *dirent;
72
73                 mail->mail_count = mail->new_mail_count = 0;
74                 dirname = (char *) malloc(sizeof(char) * (strlen(mail->box) + 5));
75                 if (!dirname) {
76                         ERR("malloc");
77                         return;
78                 }
79                 strcpy(dirname, mail->box);
80                 strcat(dirname, "/");
81                 /* checking the cur subdirectory */
82                 strcat(dirname, "cur");
83
84                 dir = opendir(dirname);
85                 if (!dir) {
86                         ERR("cannot open directory");
87                         free(dirname);
88                         return;
89                 }
90                 dirent = readdir(dir);
91                 while (dirent) {
92                         /* . and .. are skipped */
93                         if (dirent->d_name[0] != '.') {
94                                 mail->mail_count++;
95                         }
96                         dirent = readdir(dir);
97                 }
98                 closedir(dir);
99
100                 dirname[strlen(dirname) - 3] = '\0';
101                 strcat(dirname, "new");
102
103                 dir = opendir(dirname);
104                 if (!dir) {
105                         ERR("cannot open directory");
106                         free(dirname);
107                         return;
108                 }
109                 dirent = readdir(dir);
110                 while (dirent) {
111                         /* . and .. are skipped */
112                         if (dirent->d_name[0] != '.') {
113                                 mail->new_mail_count++;
114                                 mail->mail_count++;
115                         }
116                         dirent = readdir(dir);
117                 }
118                 closedir(dir);
119
120                 free(dirname);
121                 return;
122         }
123 #endif
124         /* mbox format */
125         if (buf.st_mtime != mail->last_mtime) {
126                 /* yippee, modification time has changed, let's read mail count! */
127                 static int rep;
128                 FILE *fp;
129                 int reading_status = 0;
130
131                 /* could lock here but I don't think it's really worth it because
132                  * this isn't going to write mail spool */
133
134                 mail->new_mail_count = mail->mail_count = 0;
135
136                 fp = open_file(mail->box, &rep);
137                 if (!fp) {
138                         return;
139                 }
140
141                 /* NOTE: adds mail as new if there isn't Status-field at all */
142
143                 while (!feof(fp)) {
144                         char buf[128];
145
146                         if (fgets(buf, 128, fp) == NULL) {
147                                 break;
148                         }
149
150                         if (strncmp(buf, "From ", 5) == 0) {
151                                 /* ignore MAILER-DAEMON */
152                                 if (strncmp(buf + 5, "MAILER-DAEMON ", 14) != 0) {
153                                         mail->mail_count++;
154
155                                         if (reading_status) {
156                                                 mail->new_mail_count++;
157                                         } else {
158                                                 reading_status = 1;
159                                         }
160                                 }
161                         } else {
162                                 if (reading_status
163                                                 && strncmp(buf, "X-Mozilla-Status:", 17) == 0) {
164                                         /* check that mail isn't already read */
165                                         if (strchr(buf + 21, '0')) {
166                                                 mail->new_mail_count++;
167                                         }
168
169                                         reading_status = 0;
170                                         continue;
171                                 }
172                                 if (reading_status && strncmp(buf, "Status:", 7) == 0) {
173                                         /* check that mail isn't already read */
174                                         if (strchr(buf + 7, 'R') == NULL) {
175                                                 mail->new_mail_count++;
176                                         }
177
178                                         reading_status = 0;
179                                         continue;
180                                 }
181                         }
182
183                         /* skip until \n */
184                         while (strchr(buf, '\n') == NULL && !feof(fp)) {
185                                 fgets(buf, 128, fp);
186                         }
187                 }
188
189                 fclose(fp);
190
191                 if (reading_status) {
192                         mail->new_mail_count++;
193                 }
194
195                 mail->last_mtime = buf.st_mtime;
196         }
197 }