71944adac025df87505dd28a0260ff49bf982f41
[infodrom/newmail] / mbox.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 <sys/types.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <strings.h>
25
26 /* #define FROM_DETECTION */
27
28 struct mail {
29   char from[128];
30   char subject[128];
31   int priority;
32   off_t size;
33 };
34
35 #define HDR_LEN 128
36
37 /*
38  * Like strncpy() but with terminated result.
39  */
40 char *stringcopy(char *dest, const char *src, size_t n)
41 {
42   strncpy(dest, src, n-1);
43   dest[n-1] = '\0';
44   return dest;
45 }
46
47 int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
48 {
49   FILE *f;
50   char buf[HDR_LEN];
51   char tmp[512];
52   char *cp;
53   int inheader = 1;
54   int newmail = 0;
55
56   char from_[HDR_LEN] = "";
57   char from[HDR_LEN] = "";
58 #ifdef FROM_DETECTION
59   char to[HDR_LEN] = "";
60 #endif
61   char subject[HDR_LEN] = "";
62   int priority = 0;
63
64   if ((f = fopen(path, "r")) == NULL)
65     return 0;
66
67   if (size > 0 && fseek(f, size, SEEK_SET) != 0)
68     return 0;
69
70   while (!feof(f)) {
71     if ((cp = fgets(buf, sizeof(buf), f)) == NULL)
72       continue;
73     if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\n') {
74       buf[strlen(buf)-1] = '\0';
75     } else {
76       while (!feof(f) && fgets(tmp, sizeof(tmp), f) != NULL) {
77         if (strlen(tmp) > 0 && tmp[strlen(tmp)-1] == '\n')
78           break;
79       }
80     }
81
82     if (inheader) {
83       if (strlen(buf) == 0) {
84         inheader = 0;
85         newmail = 1;
86
87         /* TODO: display header */
88
89 #ifdef FROM_DETECTION
90         from_[0] = from[0] = to[0] = subject[0] = '\0';
91 #else
92         from_[0] = from[0] = subject[0] = '\0';
93 #endif
94         priority = 0;
95       } else {
96         if (strncasecmp(buf, "From ", 5) == 0)
97           stringcopy(from_, buf+5, sizeof(from_));
98         else if (strncasecmp(buf, "From: ", 6) == 0)
99           stringcopy(from, buf+6, sizeof(from));
100 #ifdef FROM_DETECTION
101         else if (strncasecmp(buf, "To: ", 4) == 0)
102           stringcopy(to, buf+4, sizeof(to));
103 #endif
104         else if (strncasecmp(buf, "Subject: ", 9) == 0)
105           stringcopy(subject, buf+9, sizeof(subject));
106         else if (strncasecmp(buf, "Priority: urgent", 16) == 0 && buf[16] == '\0')
107           priority = 1;
108         else if (strncasecmp(buf, "X-Priority: 1", 13) == 0 && buf[13] == '\0')
109           priority = 1;
110       }
111     } else if (strncasecmp(buf, "From ", 5) == 0) {
112       inheader = 1;
113       stringcopy(from_, buf+5, sizeof(from_));
114     }
115
116   }
117
118   return newmail;
119 }
120
121 int watch_mbox(char *path, char *prefix, off_t *size, int opt_flags)
122 {
123   struct stat st;
124   int newmail = 0;
125
126   if (stat(path, &st) == 0) {
127     if (st.st_size > *size)
128       if (access(path, R_OK) == 0) {
129         newmail = inspect_mbox(path, prefix, *size, opt_flags);
130       }
131     *size = st.st_size;
132     return newmail;
133   } else {
134     *size = 0;
135   }
136
137   return 0;
138 }