Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 188 lines (154 sloc) 4.259 kb
14c2920 Imported Upstream version 1.5.18
Antonio Radici authored
1 /*
2 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #if HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include "mutt.h"
24
25 #include <ctype.h>
26 #include <string.h>
27
28 static const char *next_word (const char *s)
29 {
30 while (*s && !ISSPACE (*s))
31 s++;
32 SKIPWS (s);
33 return s;
34 }
35
36 int mutt_check_month (const char *s)
37 {
38 int i;
39
40 for (i = 0; i < 12; i++)
41 if (mutt_strncasecmp (s, Months[i], 3) == 0)
42 return (i);
43 return (-1); /* error */
44 }
45
46 static int is_day_name (const char *s)
47 {
48 int i;
49
50 if ((strlen (s) < 3) || !*(s + 3) || !ISSPACE (*(s+3)))
51 return 0;
52 for (i=0; i<7; i++)
53 if (mutt_strncasecmp (s, Weekdays[i], 3) == 0)
54 return 1;
55 return 0;
56 }
57
58 /*
59 * A valid message separator looks like:
60 *
61 * From [ <return-path> ] <weekday> <month> <day> <time> [ <timezone> ] <year>
62 */
63
64 int is_from (const char *s, char *path, size_t pathlen, time_t *tp)
65 {
66 struct tm tm;
67 int yr;
68
69 if (path)
70 *path = 0;
71
72 if (mutt_strncmp ("From ", s, 5) != 0)
73 return 0;
74
75 s = next_word (s); /* skip over the From part. */
76 if (!*s)
77 return 0;
78
79 dprint (3, (debugfile, "\nis_from(): parsing: %s", s));
80
81 if (!is_day_name (s))
82 {
83 const char *p;
84 size_t len;
85 short q = 0;
86
87 for (p = s; *p && (q || !ISSPACE (*p)); p++)
88 {
89 if (*p == '\\')
90 {
91 if (*++p == '\0')
92 return 0;
93 }
94 else if (*p == '"')
95 {
96 q = !q;
97 }
98 }
99
100 if (q || !*p) return 0;
101
102 if (path)
103 {
104 len = (size_t) (p - s);
105 if (len + 1 > pathlen)
106 len = pathlen - 1;
107 memcpy (path, s, len);
108 path[len] = 0;
109 dprint (3, (debugfile, "is_from(): got return path: %s\n", path));
110 }
111
112 s = p + 1;
113 SKIPWS (s);
114 if (!*s)
115 return 0;
116
117 if (!is_day_name (s))
118 {
119 dprint(1, (debugfile, "is_from(): expected weekday, got: %s\n", s));
120 return 0;
121 }
122 }
123
124 s = next_word (s);
125 if (!*s) return 0;
126
127 /* do a quick check to make sure that this isn't really the day of the week.
128 * this could happen when receiving mail from a local user whose login name
129 * is the same as a three-letter abbreviation of the day of the week.
130 */
131 if (is_day_name (s))
132 {
133 s = next_word (s);
134 if (!*s) return 0;
135 }
136
137 /* now we should be on the month. */
138 if ((tm.tm_mon = mutt_check_month (s)) < 0) return 0;
139
140 /* day */
141 s = next_word (s);
142 if (!*s) return 0;
143 if (sscanf (s, "%d", &tm.tm_mday) != 1) return 0;
144
145 /* time */
146 s = next_word (s);
147 if (!*s) return 0;
148
149 /* Accept either HH:MM or HH:MM:SS */
150 if (sscanf (s, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 3);
151 else if (sscanf (s, "%d:%d", &tm.tm_hour, &tm.tm_min) == 2)
152 tm.tm_sec = 0;
153 else
154 return 0;
155
156 s = next_word (s);
157 if (!*s) return 0;
158
159 /* timezone? */
160 if (isalpha ((unsigned char) *s) || *s == '+' || *s == '-')
161 {
162 s = next_word (s);
163 if (!*s) return 0;
164
165 /*
166 * some places have two timezone fields after the time, e.g.
167 * From xxxx@yyyyyyy.fr Wed Aug 2 00:39:12 MET DST 1995
168 */
169 if (isalpha ((unsigned char) *s))
170 {
171 s = next_word (s);
172 if (!*s) return 0;
173 }
174 }
175
176 /* year */
177 if (sscanf (s, "%d", &yr) != 1) return 0;
178 tm.tm_year = yr > 1900 ? yr - 1900 : (yr < 70 ? yr + 100 : yr);
179
180 dprint (3,(debugfile, "is_from(): month=%d, day=%d, hr=%d, min=%d, sec=%d, yr=%d.\n",
181 tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year));
182
183 tm.tm_isdst = -1;
184
185 if (tp) *tp = mutt_mktime (&tm, 0);
186 return 1;
187 }
Something went wrong with that request. Please try again.