Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/dll/possum/head.c
1069 views
1
/* $OpenBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */
2
/* $NetBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */
3
4
/*
5
* Copyright (c) 1980, 1993
6
* The Regents of the University of California. All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. All advertising materials mentioning features or use of this software
17
* must display the following acknowledgement:
18
* This product includes software developed by the University of
19
* California, Berkeley and its contributors.
20
* 4. Neither the name of the University nor the names of its contributors
21
* may be used to endorse or promote products derived from this software
22
* without specific prior written permission.
23
*
24
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
* SUCH DAMAGE.
35
*/
36
37
/*#include "def.h"*/
38
#include "head.h"
39
40
/*
41
* Mail -- a mail program
42
*
43
* Routines for processing and detecting headlines.
44
*/
45
46
/*
47
* See if the passed line buffer is a mail header.
48
* Return true if yes. Note the extreme pains to
49
* accomodate all funny formats.
50
*/
51
int ishead(char *linebuf)
52
{
53
register char *cp;
54
struct headline hl;
55
char parbuf[BUFSIZ];
56
57
cp = linebuf;
58
if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
59
*cp++ != ' ')
60
return (0);
61
parse(linebuf, &hl, parbuf);
62
if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
63
fail(linebuf, "No from or date field");
64
return (0);
65
}
66
if (!isdate(hl.l_date)) {
67
fail(linebuf, "Date field not legal date");
68
return (0);
69
}
70
/*
71
* I guess we got it!
72
*/
73
return (1);
74
}
75
76
/*ARGSUSED*/
77
void fail(char *linebuf, char *reason)
78
{
79
80
/*
81
if (value("debug") == NOSTR)
82
return;
83
fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);
84
*/
85
}
86
87
/*
88
* Split a headline into its useful components.
89
* Copy the line into dynamic string space, then set
90
* pointers into the copied line in the passed headline
91
* structure. Actually, it scans.
92
*/
93
void parse(char *line, register struct headline *hl, char *pbuf)
94
{
95
register char *cp;
96
char *sp;
97
char word[LINESIZE];
98
99
hl->l_from = NOSTR;
100
hl->l_tty = NOSTR;
101
hl->l_date = NOSTR;
102
cp = line;
103
sp = pbuf;
104
/*
105
* Skip over "From" first.
106
*/
107
cp = nextword(cp, word);
108
cp = nextword(cp, word);
109
if (*word)
110
hl->l_from = copyin(word, &sp);
111
if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
112
cp = nextword(cp, word);
113
hl->l_tty = copyin(word, &sp);
114
}
115
if (cp != NOSTR)
116
hl->l_date = copyin(cp, &sp);
117
}
118
119
/*
120
* Copy the string on the left into the string on the right
121
* and bump the right (reference) string pointer by the length.
122
* Thus, dynamically allocate space in the right string, copying
123
* the left string into it.
124
*/
125
char * copyin(register char *src, char **space)
126
{
127
register char *cp;
128
char *top;
129
130
top = cp = *space;
131
while ((*cp++ = *src++) != '\0')
132
;
133
*space = cp;
134
return (top);
135
}
136
137
/*
138
* Test to see if the passed string is a ctime(3) generated
139
* date string as documented in the manual. The template
140
* below is used as the criterion of correctness.
141
* Also, we check for a possible trailing time zone using
142
* the tmztype template.
143
*/
144
145
/*
146
* 'A' An upper case char
147
* 'a' A lower case char
148
* ' ' A space
149
* '0' A digit
150
* 'O' An optional digit or space
151
* ':' A colon
152
* 'N' A new line
153
*/
154
char ctype[] = "Aaa Aaa O0 00:00:00 0000";
155
char ctype_without_secs[] = "Aaa Aaa O0 00:00 0000";
156
char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000";
157
char tmztype_without_secs[] = "Aaa Aaa O0 00:00 AAA 0000";
158
159
int isdate(char *date)
160
{
161
return cmatch(date, ctype_without_secs) ||
162
cmatch(date, tmztype_without_secs) ||
163
cmatch(date, ctype) || cmatch(date, tmztype);
164
}
165
166
/*
167
* Match the given string (cp) against the given template (tp).
168
* Return 1 if they match, 0 if they don't
169
*/
170
int cmatch(register char *cp, register char *tp)
171
{
172
173
while (*cp && *tp)
174
switch (*tp++) {
175
case 'a':
176
if (!islower(*cp++))
177
return 0;
178
break;
179
case 'A':
180
if (!isupper(*cp++))
181
return 0;
182
break;
183
case ' ':
184
if (*cp++ != ' ')
185
return 0;
186
break;
187
case '0':
188
if (!isdigit(*cp++))
189
return 0;
190
break;
191
case 'O':
192
if (*cp != ' ' && !isdigit(*cp))
193
return 0;
194
cp++;
195
break;
196
case ':':
197
if (*cp++ != ':')
198
return 0;
199
break;
200
case 'N':
201
if (*cp++ != '\n')
202
return 0;
203
break;
204
}
205
if (*cp || *tp)
206
return 0;
207
return (1);
208
}
209
210
/*
211
* Collect a liberal (space, tab delimited) word into the word buffer
212
* passed. Also, return a pointer to the next word following that,
213
* or NOSTR if none follow.
214
*/
215
char *nextword(register char *wp, register char *wbuf)
216
{
217
register char c;
218
219
if (wp == NOSTR) {
220
*wbuf = 0;
221
return (NOSTR);
222
}
223
while ((c = *wp++) && c != ' ' && c != '\t') {
224
*wbuf++ = c;
225
if (c == '"') {
226
while ((c = *wp++) && c != '"')
227
*wbuf++ = c;
228
if (c == '"')
229
*wbuf++ = c;
230
else
231
wp--;
232
}
233
}
234
*wbuf = '\0';
235
for (; c == ' ' || c == '\t'; c = *wp++)
236
;
237
if (c == 0)
238
return (NOSTR);
239
return (wp - 1);
240
}
241
242