BSD 3 development
[unix-history] / .ref-BSD-2 / src / Mail / head.c
CommitLineData
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
18ishead(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
49parse(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
86isname(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
116char 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
118isdate(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
171char *
172nextword(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
196isalpha(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
208isdigit(c)
209{
210 return(c >= '0' && c <= '9');
211}
212
213/*
214 * Copy str1 to str2, return pointer to null in str2.
215 */
216
217char *
218copy(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
235any(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
253raise(c)
254 register int c;
255{
256 if (c >= 'a' && c <= 'z')
257 c += 'A' - 'a';
258 return(c);
259}