Commit | Line | Data |
---|---|---|
2cfa7fbb KS |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | # | |
3 | ||
4 | #include "def.h" | |
5 | ||
6 | /* | |
7 | * Mail -- a mail program | |
8 | * | |
9 | * Routines for processing and detecting headlines. | |
10 | */ | |
11 | ||
12 | /* | |
13 | * See if the passed line buffer is a mail header. | |
14 | * Return true if yes. Note the extreme pains to | |
15 | * accomodate all funny formats. | |
16 | */ | |
17 | ||
18 | ishead(linebuf) | |
19 | char linebuf[]; | |
20 | { | |
21 | register char *cp; | |
22 | struct headline hl; | |
23 | ||
24 | cp = linebuf; | |
25 | if (!isname("From ", cp, 5)) | |
26 | return(0); | |
27 | parse(cp, &hl); | |
28 | if (hl.l_from == NOSTR || hl.l_date == NOSTR) | |
29 | return(0); | |
30 | if (strlen(hl.l_from) >= 17) | |
31 | return(0); | |
32 | if (!isdate(hl.l_date)) | |
33 | return(0); | |
34 | ||
35 | /* | |
36 | * I guess we got it! | |
37 | */ | |
38 | ||
39 | return(1); | |
40 | } | |
41 | ||
42 | /* | |
43 | * Split a headline into its useful components. | |
44 | * Copy the line into dynamic string space, then set | |
45 | * pointers into the copied line in the passed headline | |
46 | * structure. Actually, it scans. | |
47 | */ | |
48 | ||
49 | parse(line, hl) | |
50 | char line[]; | |
51 | struct headline *hl; | |
52 | { | |
53 | register char *cp, *dp; | |
54 | char word[LINESIZE]; | |
55 | ||
56 | hl->l_from = NOSTR; | |
57 | hl->l_tty = NOSTR; | |
58 | hl->l_date = NOSTR; | |
59 | cp = line; | |
60 | ||
61 | /* | |
62 | * Skip the first "word" of the line, which should be "From" | |
63 | * anyway. | |
64 | */ | |
65 | ||
66 | cp = nextword(cp, word); | |
67 | dp = nextword(cp, word); | |
68 | if (!equal(word, "")) | |
69 | hl->l_from = savestr(word); | |
70 | if (isname(dp, "tty", 3)) { | |
71 | cp = nextword(dp, word); | |
72 | hl->l_tty = savestr(word); | |
73 | if (cp != NOSTR) | |
74 | hl->l_date = savestr(cp); | |
75 | } | |
76 | else | |
77 | if (dp != NOSTR) | |
78 | hl->l_date = savestr(dp); | |
79 | } | |
80 | ||
81 | /* | |
82 | * See if the two passed strings agree in the first n characters. | |
83 | * Return true if they do, gnu. | |
84 | */ | |
85 | ||
86 | isname(as1, as2, acount) | |
87 | char *as1, *as2; | |
88 | { | |
89 | register char *s1, *s2; | |
90 | register count; | |
91 | ||
92 | s1 = as1; | |
93 | s2 = as2; | |
94 | count = acount; | |
95 | if (count > 0) | |
96 | do | |
97 | if (*s1++ != *s2++) | |
98 | return(0); | |
99 | while (--count); | |
100 | return(1); | |
101 | } | |
102 | ||
103 | /* | |
104 | * Test to see if the passed string is a ctime(3) generated | |
105 | * date string as documented in the manual. The template | |
106 | * below is used as the criterion of correctness. | |
107 | */ | |
108 | ||
109 | #define L 1 /* An alpha char */ | |
110 | #define S 2 /* A space */ | |
111 | #define D 3 /* A digit */ | |
112 | #define O 4 /* An optional digit or space */ | |
113 | #define C 5 /* A colon */ | |
114 | #define N 6 /* A new line */ | |
115 | ||
116 | char ctypes[] = {L,L,L,S,L,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0}; | |
117 | ||
118 | isdate(date) | |
119 | char date[]; | |
120 | { | |
121 | register char *cp, *tp; | |
122 | register int c; | |
123 | ||
124 | cp = date; | |
125 | tp = ctypes; | |
126 | while (*cp != '\0' && *tp != 0) { | |
127 | c = *cp++; | |
128 | switch (*tp++) { | |
129 | case L: | |
130 | if (!isalpha(c)) | |
131 | return(0); | |
132 | break; | |
133 | ||
134 | case S: | |
135 | if (c != ' ') | |
136 | return(0); | |
137 | break; | |
138 | ||
139 | case D: | |
140 | if (!isdigit(c)) | |
141 | return(0); | |
142 | break; | |
143 | ||
144 | case O: | |
145 | if (c != ' ' && !isdigit(c)) | |
146 | return(0); | |
147 | break; | |
148 | ||
149 | case C: | |
150 | if (c != ':') | |
151 | return(0); | |
152 | break; | |
153 | ||
154 | case N: | |
155 | if (c != '\n') | |
156 | return(0); | |
157 | break; | |
158 | } | |
159 | } | |
160 | if (*cp != '\0' || *tp != 0) | |
161 | return(0); | |
162 | return(1); | |
163 | } | |
164 | ||
165 | /* | |
166 | * Collect a liberal (space, tab delimited) word into the word buffer | |
167 | * passed. Also, return a pointer to the next word following that, | |
168 | * or NOSTR if none follow. | |
169 | */ | |
170 | ||
171 | char * | |
172 | nextword(wp, wbuf) | |
173 | char wp[], wbuf[]; | |
174 | { | |
175 | register char *cp, *cp2; | |
176 | ||
177 | if ((cp = wp) == NOSTR) { | |
178 | copy("", wbuf); | |
179 | return(NOSTR); | |
180 | } | |
181 | cp2 = wbuf; | |
182 | while (!any(*cp, " \t") && *cp != '\0') | |
183 | *cp2++ = *cp++; | |
184 | *cp2 = '\0'; | |
185 | while (any(*cp, " \t")) | |
186 | cp++; | |
187 | if (*cp == '\0') | |
188 | return(NOSTR); | |
189 | return(cp); | |
190 | } | |
191 | ||
192 | /* | |
193 | * Test to see if the character is an ascii alphabetic. | |
194 | */ | |
195 | ||
196 | isalpha(c) | |
197 | { | |
198 | register int ch; | |
199 | ||
200 | ch = raise(c); | |
201 | return(ch >= 'A' && ch <= 'Z'); | |
202 | } | |
203 | ||
204 | /* | |
205 | * Test to see if the character is an ascii digit. | |
206 | */ | |
207 | ||
208 | isdigit(c) | |
209 | { | |
210 | return(c >= '0' && c <= '9'); | |
211 | } | |
212 | ||
213 | /* | |
214 | * Copy str1 to str2, return pointer to null in str2. | |
215 | */ | |
216 | ||
217 | char * | |
218 | copy(str1, str2) | |
219 | char *str1, *str2; | |
220 | { | |
221 | register char *s1, *s2; | |
222 | ||
223 | s1 = str1; | |
224 | s2 = str2; | |
225 | while (*s1) | |
226 | *s2++ = *s1++; | |
227 | *s2 = 0; | |
228 | return(s2); | |
229 | } | |
230 | ||
231 | /* | |
232 | * Is ch any of the characters in str? | |
233 | */ | |
234 | ||
235 | any(ch, str) | |
236 | char *str; | |
237 | { | |
238 | register char *f; | |
239 | register c; | |
240 | ||
241 | f = str; | |
242 | c = ch; | |
243 | while (*f) | |
244 | if (c == *f++) | |
245 | return(1); | |
246 | return(0); | |
247 | } | |
248 | ||
249 | /* | |
250 | * Convert lower case letters to upper case. | |
251 | */ | |
252 | ||
253 | raise(c) | |
254 | register int c; | |
255 | { | |
256 | if (c >= 'a' && c <= 'z') | |
257 | c += 'A' - 'a'; | |
258 | return(c); | |
259 | } |