completely stupid mistake.
[apps/madmutt.git] / from.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #include <lib-lib/lib-lib.h>
11
12 #include "mutt.h"
13
14 int mutt_check_month (const char *s)
15 {
16   int i;
17
18   for (i = 0; i < 12; i++)
19     if (m_strncasecmp(s, Months[i], 3) == 0)
20       return (i);
21   return (-1);                  /* error */
22 }
23
24 static int is_day_name (const char *s)
25 {
26   int i;
27
28   if ((m_strlen(s) < 3) || !*(s + 3) || !ISSPACE (*(s + 3)))
29     return 0;
30   for (i = 0; i < 7; i++)
31     if (m_strncasecmp(s, Weekdays[i], 3) == 0)
32       return 1;
33   return 0;
34 }
35
36 /*
37  * A valid message separator looks like:
38  *
39  * From [ <return-path> ] <weekday> <month> <day> <time> [ <timezone> ] <year>
40  */
41
42 int is_from (const char *s, char *path, ssize_t pathlen, time_t * tp)
43 {
44   struct tm tm;
45   int yr;
46
47   if (path)
48     *path = 0;
49
50   if (m_strncmp("From ", s, 5) != 0)
51     return 0;
52
53   s = m_strnextsp(s);            /* skip over the From part. */
54   s = skipspaces(s);
55   if (!*s)
56     return 0;
57
58   if (!is_day_name (s)) {
59     const char *p;
60     ssize_t len;
61     short q = 0;
62
63     for (p = s; *p && (q || !ISSPACE (*p)); p++) {
64       if (*p == '\\') {
65         if (*++p == '\0')
66           return 0;
67       }
68       else if (*p == '"') {
69         q = !q;
70       }
71     }
72
73     if (q || !*p)
74       return 0;
75
76     if (path) {
77       len = p - s;
78       if (len + 1 > pathlen)
79         len = pathlen - 1;
80       memcpy (path, s, len);
81       path[len] = 0;
82     }
83
84     s = vskipspaces(p + 1);
85     if (!*s)
86       return 0;
87
88     if (!is_day_name (s)) {
89       return 0;
90     }
91   }
92
93   s = m_strnextsp(s);
94   s = skipspaces(s);
95   if (!*s)
96     return 0;
97
98   /* do a quick check to make sure that this isn't really the day of the week.
99    * this could happen when receiving mail from a local user whose login name
100    * is the same as a three-letter abbreviation of the day of the week.
101    */
102   if (is_day_name (s)) {
103     s = m_strnextsp(s);
104     s = skipspaces(s);
105     if (!*s)
106       return 0;
107   }
108
109   /* now we should be on the month. */
110   if ((tm.tm_mon = mutt_check_month (s)) < 0)
111     return 0;
112
113   /* day */
114   s = m_strnextsp(s);
115   s = skipspaces(s);
116   if (!*s)
117     return 0;
118   if (sscanf (s, "%d", &tm.tm_mday) != 1)
119     return 0;
120
121   /* time */
122   s = m_strnextsp(s);
123   s = skipspaces(s);
124   if (!*s)
125     return 0;
126
127   /* Accept either HH:MM or HH:MM:SS */
128   if (sscanf (s, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 3);
129   else if (sscanf (s, "%d:%d", &tm.tm_hour, &tm.tm_min) == 2)
130     tm.tm_sec = 0;
131   else
132     return 0;
133
134   s = m_strnextsp(s);
135   s = skipspaces(s);
136   if (!*s)
137     return 0;
138
139   /* timezone? */
140   if (isalpha ((unsigned char) *s) || *s == '+' || *s == '-') {
141     s = m_strnextsp(s);
142     s = skipspaces(s);
143     if (!*s)
144       return 0;
145
146     /*
147      * some places have two timezone fields after the time, e.g.
148      *      From xxxx@yyyyyyy.fr Wed Aug  2 00:39:12 MET DST 1995
149      */
150     if (isalpha ((unsigned char) *s)) {
151       s = m_strnextsp(s);
152       s = skipspaces(s);
153       if (!*s)
154         return 0;
155     }
156   }
157
158   /* year */
159   if (sscanf (s, "%d", &yr) != 1)
160     return 0;
161   tm.tm_year = yr > 1900 ? yr - 1900 : (yr < 70 ? yr + 100 : yr);
162
163   tm.tm_isdst = -1;
164
165   if (tp)
166     *tp = mutt_mktime (&tm, 0);
167   return 1;
168 }