annotate sbr/m_getfld.c @ 3:f89a9a79e124

utf-8
author kono
date Wed, 20 Apr 2005 00:25:01 +0900
parents bce86c4163a3
children 441a2190cfae
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
bce86c4163a3 Initial revision
kono
parents:
diff changeset
1 /* m_getfld.c - read/parse a message */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
2 #ifndef lint
bce86c4163a3 Initial revision
kono
parents:
diff changeset
3 static char ident[] = "@(#)$Id$";
bce86c4163a3 Initial revision
kono
parents:
diff changeset
4 #endif /* lint */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
5
bce86c4163a3 Initial revision
kono
parents:
diff changeset
6 #include "../h/mh.h"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
7 #include <stdio.h>
bce86c4163a3 Initial revision
kono
parents:
diff changeset
8 #include "../zotnet/mts.h"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
9 #include <ctype.h>
bce86c4163a3 Initial revision
kono
parents:
diff changeset
10
bce86c4163a3 Initial revision
kono
parents:
diff changeset
11
bce86c4163a3 Initial revision
kono
parents:
diff changeset
12 /* This module has a long and checkered history. First, it didn't burst
bce86c4163a3 Initial revision
kono
parents:
diff changeset
13 maildrops correctly because it considered two CTRL-A:s in a row to be
bce86c4163a3 Initial revision
kono
parents:
diff changeset
14 an inter-message delimiter. It really is four CTRL-A:s followed by a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
15 newline. Unfortunately, MMDF will convert this delimiter *inside* a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
16 message to a CTRL-B followed by three CTRL-A:s and a newline. This
bce86c4163a3 Initial revision
kono
parents:
diff changeset
17 caused the old version of m_getfld() to declare eom prematurely. The
bce86c4163a3 Initial revision
kono
parents:
diff changeset
18 fix was a lot slower than
bce86c4163a3 Initial revision
kono
parents:
diff changeset
19
bce86c4163a3 Initial revision
kono
parents:
diff changeset
20 c == '\001' && peekc (iob) == '\001'
bce86c4163a3 Initial revision
kono
parents:
diff changeset
21
bce86c4163a3 Initial revision
kono
parents:
diff changeset
22 but it worked, and to increase generality, UUCP style maildrops could
bce86c4163a3 Initial revision
kono
parents:
diff changeset
23 be parsed as well. Unfortunately the speed issue finally caught up with
bce86c4163a3 Initial revision
kono
parents:
diff changeset
24 us since this routine is at the very heart of MH.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
25
bce86c4163a3 Initial revision
kono
parents:
diff changeset
26 To speed things up considerably, the routine Eom() was made an auxilary
bce86c4163a3 Initial revision
kono
parents:
diff changeset
27 function called by the macro eom(). Unless we are bursting a maildrop,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
28 the eom() macro returns FALSE saying we aren't at the end of the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
29 message.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
30
bce86c4163a3 Initial revision
kono
parents:
diff changeset
31 The next thing to do is to read the mtstailor file and initialize
bce86c4163a3 Initial revision
kono
parents:
diff changeset
32 delimiter[] and delimlen accordingly...
bce86c4163a3 Initial revision
kono
parents:
diff changeset
33
bce86c4163a3 Initial revision
kono
parents:
diff changeset
34 After mhl was made a built-in in msh, m_getfld() worked just fine
bce86c4163a3 Initial revision
kono
parents:
diff changeset
35 (using m_unknown() at startup). Until one day: a message which was
bce86c4163a3 Initial revision
kono
parents:
diff changeset
36 the result of a bursting was shown. Then, since the burst boundaries
bce86c4163a3 Initial revision
kono
parents:
diff changeset
37 aren't CTRL-A:s, m_getfld() would blinding plunge on past the boundary.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
38 Very sad. The solution: introduce m_eomsbr(). This hook gets called
bce86c4163a3 Initial revision
kono
parents:
diff changeset
39 after the end of each line (since testing for eom involves an fseek()).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
40 This worked fine, until one day: a message with no body portion arrived.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
41 Then the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
42
bce86c4163a3 Initial revision
kono
parents:
diff changeset
43 while (eom (c = Getc (iob), iob))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
44 continue;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
45
bce86c4163a3 Initial revision
kono
parents:
diff changeset
46 loop caused m_getfld() to return FMTERR. So, that logic was changed to
bce86c4163a3 Initial revision
kono
parents:
diff changeset
47 check for (*eom_action) and act accordingly.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
48
bce86c4163a3 Initial revision
kono
parents:
diff changeset
49 This worked fine, until one day: someone didn't use four CTRL:A's as
bce86c4163a3 Initial revision
kono
parents:
diff changeset
50 their delimiters. So, the bullet got bit and we read mts.h and
bce86c4163a3 Initial revision
kono
parents:
diff changeset
51 continue to struggle on. It's not that bad though, since the only time
bce86c4163a3 Initial revision
kono
parents:
diff changeset
52 the code gets executed is when inc (or msh) calls it, and both of these
bce86c4163a3 Initial revision
kono
parents:
diff changeset
53 have already called mts_init().
bce86c4163a3 Initial revision
kono
parents:
diff changeset
54
bce86c4163a3 Initial revision
kono
parents:
diff changeset
55 ------------------------
bce86c4163a3 Initial revision
kono
parents:
diff changeset
56 (Written by Van Jacobson for the mh6 m_getfld, January, 1986):
bce86c4163a3 Initial revision
kono
parents:
diff changeset
57
bce86c4163a3 Initial revision
kono
parents:
diff changeset
58 This routine was accounting for 60% of the cpu time used by most mh
bce86c4163a3 Initial revision
kono
parents:
diff changeset
59 programs. I spent a bit of time tuning and it now accounts for <10%
bce86c4163a3 Initial revision
kono
parents:
diff changeset
60 of the time used. Like any heavily tuned routine, it's a bit
bce86c4163a3 Initial revision
kono
parents:
diff changeset
61 complex and you want to be sure you understand everything that it's
bce86c4163a3 Initial revision
kono
parents:
diff changeset
62 doing before you start hacking on it. Let me try to emphasize
bce86c4163a3 Initial revision
kono
parents:
diff changeset
63 that: every line in this atrocity depends on every other line,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
64 sometimes in subtle ways. You should understand it all, in detail,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
65 before trying to change any part. If you do change it, test the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
66 result thoroughly (I use a hand-constructed test file that exercises
bce86c4163a3 Initial revision
kono
parents:
diff changeset
67 all the ways a header name, header body, header continuation,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
68 header-body separator, body line and body eom can align themselves
bce86c4163a3 Initial revision
kono
parents:
diff changeset
69 with respect to a buffer boundary). "Minor" bugs in this routine
bce86c4163a3 Initial revision
kono
parents:
diff changeset
70 result in garbaged or lost mail.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
71
bce86c4163a3 Initial revision
kono
parents:
diff changeset
72 If you hack on this and slow it down, I, my children and my
bce86c4163a3 Initial revision
kono
parents:
diff changeset
73 children's children will curse you.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
74
bce86c4163a3 Initial revision
kono
parents:
diff changeset
75 This routine gets used on three different types of files: normal,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
76 single msg files, "packed" unix or mmdf mailboxs (when used by inc)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
77 and packed, directoried bulletin board files (when used by msh).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
78 The biggest impact of different file types is in "eom" testing. The
bce86c4163a3 Initial revision
kono
parents:
diff changeset
79 code has been carefully organized to test for eom at appropriate
bce86c4163a3 Initial revision
kono
parents:
diff changeset
80 times and at no other times (since the check is quite expensive).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
81 I have tried to arrange things so that the eom check need only be
bce86c4163a3 Initial revision
kono
parents:
diff changeset
82 done on entry to this routine. Since an eom can only occur after a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
83 newline, this is easy to manage for header fields. For the msg
bce86c4163a3 Initial revision
kono
parents:
diff changeset
84 body, we try to efficiently search the input buffer to see if
bce86c4163a3 Initial revision
kono
parents:
diff changeset
85 contains the eom delimiter. If it does, we take up to the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
86 delimiter, otherwise we take everything in the buffer. (The change
bce86c4163a3 Initial revision
kono
parents:
diff changeset
87 to the body eom/copy processing produced the most noticeable
bce86c4163a3 Initial revision
kono
parents:
diff changeset
88 performance difference, particularly for "inc" and "show".)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
89
bce86c4163a3 Initial revision
kono
parents:
diff changeset
90 There are three qualitatively different things this routine busts
bce86c4163a3 Initial revision
kono
parents:
diff changeset
91 out of a message: field names, field text and msg bodies. Field
bce86c4163a3 Initial revision
kono
parents:
diff changeset
92 names are typically short (~8 char) and the loop that extracts them
bce86c4163a3 Initial revision
kono
parents:
diff changeset
93 might terminate on a colon, newline or max width. I considered
bce86c4163a3 Initial revision
kono
parents:
diff changeset
94 using a Vax "scanc" to locate the end of the field followed by a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
95 "bcopy" but the routine call overhead on a Vax is too large for this
bce86c4163a3 Initial revision
kono
parents:
diff changeset
96 to work on short names. If Berkeley ever makes "inline" part of the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
97 C optimiser (so things like "scanc" turn into inline instructions) a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
98 change here would be worthwhile.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
99
bce86c4163a3 Initial revision
kono
parents:
diff changeset
100 Field text is typically 60 - 100 characters so there's (barely)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
101 a win in doing a routine call to something that does a "locc"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
102 followed by a "bmove". About 30% of the fields have continuations
bce86c4163a3 Initial revision
kono
parents:
diff changeset
103 (usually the 822 "received:" lines) and each continuation generates
bce86c4163a3 Initial revision
kono
parents:
diff changeset
104 another routine call. "Inline" would be a big win here, as well.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
105
bce86c4163a3 Initial revision
kono
parents:
diff changeset
106 Messages, as of this writing, seem to come in two flavors: small
bce86c4163a3 Initial revision
kono
parents:
diff changeset
107 (~1K) and long (>2K). Most messages have 400 - 600 bytes of headers
bce86c4163a3 Initial revision
kono
parents:
diff changeset
108 so message bodies average at least a few hundred characters.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
109 Assuming your system uses reasonably sized stdio buffers (1K or
bce86c4163a3 Initial revision
kono
parents:
diff changeset
110 more), this routine should be able to remove the body in large
bce86c4163a3 Initial revision
kono
parents:
diff changeset
111 (>500 byte) chunks. The makes the cost of a call to "bcopy"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
112 small but there is a premium on checking for the eom in packed
bce86c4163a3 Initial revision
kono
parents:
diff changeset
113 maildrops. The eom pattern is always a simple string so we can
bce86c4163a3 Initial revision
kono
parents:
diff changeset
114 construct an efficient pattern matcher for it (e.g., a Vax "matchc"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
115 instruction). Some thought went into recognizing the start of
bce86c4163a3 Initial revision
kono
parents:
diff changeset
116 an eom that has been split across two buffers.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
117
bce86c4163a3 Initial revision
kono
parents:
diff changeset
118 This routine wants to deal with large chunks of data so, rather
bce86c4163a3 Initial revision
kono
parents:
diff changeset
119 than "getc" into a local buffer, it uses stdio's buffer. If
bce86c4163a3 Initial revision
kono
parents:
diff changeset
120 you try to use it on a non-buffered file, you'll get what you
bce86c4163a3 Initial revision
kono
parents:
diff changeset
121 deserve. This routine "knows" that struct FILEs have a _ptr
bce86c4163a3 Initial revision
kono
parents:
diff changeset
122 and a _cnt to describe the current state of the buffer and
bce86c4163a3 Initial revision
kono
parents:
diff changeset
123 it knows that _filbuf ignores the _ptr & _cnt and simply fills
bce86c4163a3 Initial revision
kono
parents:
diff changeset
124 the buffer. If stdio on your system doesn't work this way, you
bce86c4163a3 Initial revision
kono
parents:
diff changeset
125 may have to make small changes in this routine.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
126
bce86c4163a3 Initial revision
kono
parents:
diff changeset
127 This routine also "knows" that an EOF indication on a stream is
bce86c4163a3 Initial revision
kono
parents:
diff changeset
128 "sticky" (i.e., you will keep getting EOF until you reposition the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
129 stream). If your system doesn't work this way it is broken and you
bce86c4163a3 Initial revision
kono
parents:
diff changeset
130 should complain to the vendor. As a consequence of the sticky
bce86c4163a3 Initial revision
kono
parents:
diff changeset
131 EOF, this routine will never return any kind of EOF status when
bce86c4163a3 Initial revision
kono
parents:
diff changeset
132 there is data in "name" or "buf").
bce86c4163a3 Initial revision
kono
parents:
diff changeset
133 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
134
bce86c4163a3 Initial revision
kono
parents:
diff changeset
135
bce86c4163a3 Initial revision
kono
parents:
diff changeset
136 #define Getc(iob) getc(iob)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
137 #define eom(c,iob) (msg_style != MS_DEFAULT && \
bce86c4163a3 Initial revision
kono
parents:
diff changeset
138 (((c) == *msg_delim && m_Eom(c,iob)) ||\
bce86c4163a3 Initial revision
kono
parents:
diff changeset
139 (eom_action && (*eom_action)(c))))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
140
bce86c4163a3 Initial revision
kono
parents:
diff changeset
141 static unsigned char *matchc();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
142 static unsigned char *locc();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
143
bce86c4163a3 Initial revision
kono
parents:
diff changeset
144 static unsigned char **pat_map;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
145
bce86c4163a3 Initial revision
kono
parents:
diff changeset
146 extern int msg_count; /* defined in sbr/m_msgdef.c = 0
bce86c4163a3 Initial revision
kono
parents:
diff changeset
147 * disgusting hack for "inc" so it can
bce86c4163a3 Initial revision
kono
parents:
diff changeset
148 * know how many characters were stuffed
bce86c4163a3 Initial revision
kono
parents:
diff changeset
149 * in the buffer on the last call (see
bce86c4163a3 Initial revision
kono
parents:
diff changeset
150 * comments in uip/scansbr.c) */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
151
bce86c4163a3 Initial revision
kono
parents:
diff changeset
152 extern int msg_style; /* defined in sbr/m_msgdef.c = MS_DEFAULT */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
153 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
154 * The "full" delimiter string for a packed maildrop consists
bce86c4163a3 Initial revision
kono
parents:
diff changeset
155 * of a newline followed by the actual delimiter. E.g., the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
156 * full string for a Unix maildrop would be: "\n\nFrom ".
bce86c4163a3 Initial revision
kono
parents:
diff changeset
157 * "Fdelim" points to the start of the full string and is used
bce86c4163a3 Initial revision
kono
parents:
diff changeset
158 * in the BODY case of the main routine to search the buffer for
bce86c4163a3 Initial revision
kono
parents:
diff changeset
159 * a possible eom. Msg_delim points to the first character of
bce86c4163a3 Initial revision
kono
parents:
diff changeset
160 * the actual delim. string (i.e., fdelim+1). Edelim
bce86c4163a3 Initial revision
kono
parents:
diff changeset
161 * points to the 2nd character of actual delimiter string. It
bce86c4163a3 Initial revision
kono
parents:
diff changeset
162 * is used in m_Eom because the first character of the string
bce86c4163a3 Initial revision
kono
parents:
diff changeset
163 * has been read and matched before m_Eom is called.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
164 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
165 extern char *msg_delim; /* defined in sbr/m_msgdef.c = "" */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
166 static unsigned char *fdelim;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
167 static unsigned char *delimend;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
168 static int fdelimlen;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
169 static unsigned char *edelim;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
170 static int edelimlen;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
171
bce86c4163a3 Initial revision
kono
parents:
diff changeset
172 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
173 static int content_length = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
174 static long end_of_contents = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
175 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
176
bce86c4163a3 Initial revision
kono
parents:
diff changeset
177 static int (*eom_action) () = NULL;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
178
bce86c4163a3 Initial revision
kono
parents:
diff changeset
179 #ifdef FILE__PTR
bce86c4163a3 Initial revision
kono
parents:
diff changeset
180 #define _ptr __ptr
bce86c4163a3 Initial revision
kono
parents:
diff changeset
181 #define _cnt __cnt
bce86c4163a3 Initial revision
kono
parents:
diff changeset
182 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
183
bce86c4163a3 Initial revision
kono
parents:
diff changeset
184 #ifdef _FSTDIO
bce86c4163a3 Initial revision
kono
parents:
diff changeset
185 #define _ptr _p /* Gag */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
186 #define _cnt _r /* Retch */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
187 #define _filbuf __srget /* Puke */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
188 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
189
bce86c4163a3 Initial revision
kono
parents:
diff changeset
190 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
191
bce86c4163a3 Initial revision
kono
parents:
diff changeset
192 m_getfld (state, name, buf, bufsz, iob)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
193 int state;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
194 int bufsz;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
195 unsigned char *name,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
196 *buf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
197 register FILE *iob;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
198 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
199 register unsigned char *cp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
200 register unsigned char *bp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
201 register unsigned char *ep;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
202 register unsigned char *sp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
203 register int cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
204 register int c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
205 register int i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
206 register int j;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
207
bce86c4163a3 Initial revision
kono
parents:
diff changeset
208 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
209 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
210 * When starting to read from a new file, we have to reset the state,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
211 * but only if the state wasn't reset. That may save us a number of
bce86c4163a3 Initial revision
kono
parents:
diff changeset
212 * lseeks.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
213 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
214 if (state == FLD &&
bce86c4163a3 Initial revision
kono
parents:
diff changeset
215 (content_length != -1 || end_of_contents != -1) &&
bce86c4163a3 Initial revision
kono
parents:
diff changeset
216 ftell(iob) == 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
217 end_of_contents = content_length = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
218 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
219 if ((c = Getc(iob)) < 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
220 msg_count = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
221 *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
222 return FILEEOF;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
223 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
224 if (eom (c, iob)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
225 if (! eom_action) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
226 /* flush null messages */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
227 while ((c = Getc(iob)) >= 0 && eom (c, iob))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
228 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
229 if (c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
230 (void) ungetc(c, iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
231 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
232 msg_count = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
233 *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
234 return FILEEOF;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
235 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
236
bce86c4163a3 Initial revision
kono
parents:
diff changeset
237 switch (state) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
238 case FLDEOF:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
239 case BODYEOF:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
240 case FLD:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
241 if (c == '\n' || c == '-') {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
242 /* we hit the header/body separator */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
243 while (c != '\n' && (c = Getc(iob)) >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
244 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
245
bce86c4163a3 Initial revision
kono
parents:
diff changeset
246 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
247 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
248 * When we've found a content-length header, we're
bce86c4163a3 Initial revision
kono
parents:
diff changeset
249 * going to use it to tell where the message boundary
bce86c4163a3 Initial revision
kono
parents:
diff changeset
250 * is, if it is a valid mesage boundary.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
251 * There can be a number of cases:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
252 * - no bytes after <content-length> bytes: the usual format
bce86c4163a3 Initial revision
kono
parents:
diff changeset
253 * of a message in an MH folder.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
254 * - only a newline - last message in mail drop.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
255 * - "\nFrom " - beginning of next message
bce86c4163a3 Initial revision
kono
parents:
diff changeset
256 * - other - ignore Content-Length header, but issue warning
bce86c4163a3 Initial revision
kono
parents:
diff changeset
257 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
258 if (msg_style == MS_UUCP && content_length != -1) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
259 long here = ftell(iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
260 static char delim[] = "\nFrom ";
bce86c4163a3 Initial revision
kono
parents:
diff changeset
261 char buf[sizeof(delim)-1];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
262 int cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
263
bce86c4163a3 Initial revision
kono
parents:
diff changeset
264 /* compute position of character after file */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
265 end_of_contents = here + content_length + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
266 content_length = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
267 /* And see whether this is a From header or eof. */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
268 fseek(iob, end_of_contents - 1, 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
269 cnt = fread(buf, sizeof(char), sizeof(buf), iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
270 if (cnt != 0 && (cnt != 1 || buf[0] != '\n') &&
bce86c4163a3 Initial revision
kono
parents:
diff changeset
271 (cnt != sizeof(buf) ||
bce86c4163a3 Initial revision
kono
parents:
diff changeset
272 strncmp(buf,delim, sizeof(buf)) != 0)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
273 advise (NULLCP, "invalid Content-Length: header\n");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
274 end_of_contents = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
275 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
276 fseek(iob, here, 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
277 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
278 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
279 if (c < 0 || (c = Getc(iob)) < 0 || eom (c, iob)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
280 if (! eom_action) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
281 /* flush null messages */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
282 while ((c = Getc(iob)) >= 0 && eom (c, iob))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
283 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
284 if (c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
285 (void) ungetc(c, iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
286 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
287 msg_count = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
288 *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
289 return FILEEOF;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
290 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
291 state = BODY;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
292 goto body;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
293 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
294 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
295 * get the name of this component. take characters up
bce86c4163a3 Initial revision
kono
parents:
diff changeset
296 * to a ':', a newline or NAMESZ-1 characters, whichever
bce86c4163a3 Initial revision
kono
parents:
diff changeset
297 * comes first.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
298 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
299 cp = name; i = NAMESZ - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
300 for (;;) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
301 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
302 bp = sp = (unsigned char *) iob->_IO_read_ptr - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
303 j = (cnt = ((long) iob->_IO_read_end - (long) iob->_IO_read_ptr) + 1) < i?
bce86c4163a3 Initial revision
kono
parents:
diff changeset
304 cnt: i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
305 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
306 bp = sp = (unsigned char *) iob->_ptr - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
307 j = (cnt = iob->_cnt+1) < i ? cnt : i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
308 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
309 while (--j >= 0 && (c = *bp++) != ':' && c != '\n')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
310 *cp++ = c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
311
bce86c4163a3 Initial revision
kono
parents:
diff changeset
312 j = bp - sp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
313 if ((cnt -= j) <= 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
314 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
315 iob->_IO_read_ptr = iob->_IO_read_end;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
316 if (__underflow((struct _IO_FILE *) iob) == EOF) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
317 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
318 #ifdef FILBUF_ADJ
bce86c4163a3 Initial revision
kono
parents:
diff changeset
319 iob -> _ptr += iob -> _cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
320 iob -> _cnt = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
321 #endif /* FILBUF_ADJ */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
322 if (_filbuf(iob) == EOF) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
323 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
324 *cp = *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
325 advise (NULLCP, "eof encountered in field \"%s\"",
bce86c4163a3 Initial revision
kono
parents:
diff changeset
326 name);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
327 return FMTERR;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
328 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
329 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
330 iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
331 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
332 } else {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
333 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
334 iob->_IO_read_ptr = bp + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
335 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
336 iob->_ptr = bp + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
337 iob->_cnt = cnt - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
338 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
339 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
340 if (c == ':')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
341 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
342
bce86c4163a3 Initial revision
kono
parents:
diff changeset
343 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
344 * something went wrong. possibilities are:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
345 * . hit a newline (error)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
346 * . got more than namesz chars. (error)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
347 * . hit the end of the buffer. (loop)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
348 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
349 if (c == '\n') {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
350 *cp = *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
351 advise (NULLCP, "eol encountered in field \"%s\"", name);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
352 state = FMTERR;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
353 goto finish;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
354 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
355 if ((i -= j) <= 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
356 *cp = *buf = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
357 advise (NULLCP, "field name \"%s\" exceeds %d bytes",
bce86c4163a3 Initial revision
kono
parents:
diff changeset
358 name, NAMESZ - 1);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
359 state = LENERR;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
360 goto finish;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
361 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
362 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
363
bce86c4163a3 Initial revision
kono
parents:
diff changeset
364 while (isspace (*--cp) && cp >= name)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
365 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
366 *++cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
367 /* fall through */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
368
bce86c4163a3 Initial revision
kono
parents:
diff changeset
369 case FLDPLUS:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
370 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
371 * get (more of) the text of a field. take
bce86c4163a3 Initial revision
kono
parents:
diff changeset
372 * characters up to the end of this field (newline
bce86c4163a3 Initial revision
kono
parents:
diff changeset
373 * followed by non-blank) or bufsz-1 characters.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
374 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
375 cp = buf; i = bufsz-1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
376 for (;;) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
377 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
378 cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
379 bp = (unsigned char *) --iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
380 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
381 cnt = iob->_cnt++; bp = (unsigned char *) --iob->_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
382 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
383 c = cnt < i ? cnt : i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
384 while (ep = locc( c, bp, '\n' )) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
385 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
386 * if we hit the end of this field, return.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
387 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
388 if ((j = *++ep) != ' ' && j != '\t') {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
389 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
390 j = ep - (unsigned char *) iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
391 (void) bcopy( iob->_IO_read_ptr, cp, j);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
392 iob->_IO_read_ptr = ep;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
393 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
394 j = ep - (unsigned char *) iob->_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
395 (void) bcopy( iob->_ptr, cp, j);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
396 iob->_ptr = ep; iob->_cnt -= j;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
397 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
398 cp += j;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
399 state = FLD;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
400 goto finish;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
401 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
402 c -= ep - bp; bp = ep;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
403 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
404 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
405 * end of input or dest buffer - copy what we've found.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
406 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
407 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
408 c += bp - (unsigned char *) iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
409 (void) bcopy( iob->_IO_read_ptr, cp, c);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
410 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
411 c += bp - (unsigned char *) iob->_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
412 (void) bcopy( iob->_ptr, cp, c);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
413 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
414 i -= c; cp += c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
415 if (i <= 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
416 /* the dest buffer is full */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
417 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
418 iob->_IO_read_ptr += c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
419 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
420 iob->_cnt -= c; iob->_ptr += c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
421 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
422 state = FLDPLUS;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
423 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
424 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
425 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
426 * There's one character left in the input buffer.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
427 * Copy it & fill the buffer. If the last char
bce86c4163a3 Initial revision
kono
parents:
diff changeset
428 * was a newline and the next char is not whitespace,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
429 * this is the end of the field. Otherwise loop.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
430 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
431 --i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
432 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
433 *cp++ = j = *(iob->_IO_read_ptr + c);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
434 iob->_IO_read_ptr = iob->_IO_read_end;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
435 c = __underflow((struct _IO_FILE *) iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
436 iob->_IO_read_ptr++; /* NOT automatic! */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
437 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
438 *cp++ = j = *(iob->_ptr + c);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
439 #ifdef FILBUF_ADJ
bce86c4163a3 Initial revision
kono
parents:
diff changeset
440 iob -> _ptr += iob -> _cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
441 iob -> _cnt = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
442 #endif /* FILBUF_ADJ */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
443 c = _filbuf(iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
444 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
445 /* bugfix, 03/1998.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
446 * If we encounter EOF halfway through reading the value (ie there is
bce86c4163a3 Initial revision
kono
parents:
diff changeset
447 * no trailing \n in the field) then __underflow() above returns EOF.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
448 * Previously we didn't check for this, with the result that we then
bce86c4163a3 Initial revision
kono
parents:
diff changeset
449 * attempt to read from the stream and wind up segfaulting doing a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
450 * bcopy() with length parameter -1. Instead, we just append a newline
bce86c4163a3 Initial revision
kono
parents:
diff changeset
451 * to what we've read, so the following conditional will pick it up
bce86c4163a3 Initial revision
kono
parents:
diff changeset
452 * and return the field value. Then the EOF is actually dealt with
bce86c4163a3 Initial revision
kono
parents:
diff changeset
453 * the next time this function is called.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
454 * The reason for appending \n is because the callers are known to
bce86c4163a3 Initial revision
kono
parents:
diff changeset
455 * work with 'name: value\n', and setting j to '\n' is known to exit
bce86c4163a3 Initial revision
kono
parents:
diff changeset
456 * in the right way, and the less we change the less likely
bce86c4163a3 Initial revision
kono
parents:
diff changeset
457 * we are to introduce new bugs. And I'm scared of the curse in the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
458 * comments at the top of this file :->
bce86c4163a3 Initial revision
kono
parents:
diff changeset
459 * -- PMM (pmaydell@chiark.greenend.org.uk)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
460 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
461 if (c == EOF && j != '\0' && j != '\n') {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
462 *cp++ = j = '\n';
bce86c4163a3 Initial revision
kono
parents:
diff changeset
463 advise (NULLCP, "file missing final eol");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
464 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
465 /* bugfix end */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
466 if ((j == '\0' || j == '\n') && c != ' ' && c != '\t') {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
467 if (c != EOF)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
468 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
469 --iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
470 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
471 --iob->_ptr, ++iob->_cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
472 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
473 state = FLD;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
474 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
475 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
476 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
477 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
478
bce86c4163a3 Initial revision
kono
parents:
diff changeset
479 case BODY:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
480 body:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
481 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
482 * get the message body up to bufsz characters or the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
483 * end of the message. Sleazy hack: if bufsz is negative
bce86c4163a3 Initial revision
kono
parents:
diff changeset
484 * we assume that we were called to copy directly into
bce86c4163a3 Initial revision
kono
parents:
diff changeset
485 * the output buffer and we don't add an eos.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
486 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
487 i = (bufsz < 0) ? -bufsz : bufsz-1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
488 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
489 bp = (unsigned char *) --iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
490 cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
491 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
492 bp = (unsigned char *) --iob->_ptr; cnt = ++iob->_cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
493 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
494 c = (cnt < i ? cnt : i);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
495 if (msg_style != MS_DEFAULT && c > 1) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
496 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
497 * packed maildrop - only take up to the (possible)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
498 * start of the next message. This "matchc" should
bce86c4163a3 Initial revision
kono
parents:
diff changeset
499 * probably be a Boyer-Moore matcher for non-vaxen,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
500 * particularly since we have the alignment table
bce86c4163a3 Initial revision
kono
parents:
diff changeset
501 * all built for the end-of-buffer test (next).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
502 * But our vax timings indicate that the "matchc"
bce86c4163a3 Initial revision
kono
parents:
diff changeset
503 * instruction is 50% faster than a carefully coded
bce86c4163a3 Initial revision
kono
parents:
diff changeset
504 * B.M. matcher for most strings. (So much for elegant
bce86c4163a3 Initial revision
kono
parents:
diff changeset
505 * algorithms vs. brute force.) Since I (currently)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
506 * run MH on a vax, we use the matchc instruction. --vj
bce86c4163a3 Initial revision
kono
parents:
diff changeset
507 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
508 if (ep = matchc( fdelimlen, fdelim, c, bp ) )
bce86c4163a3 Initial revision
kono
parents:
diff changeset
509 c = ep - bp + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
510 else {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
511 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
512 * There's no delim in the buffer but there may be
bce86c4163a3 Initial revision
kono
parents:
diff changeset
513 * a partial one at the end. If so, we want to leave
bce86c4163a3 Initial revision
kono
parents:
diff changeset
514 * it so the "eom" check on the next call picks it up.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
515 * Use a modified Boyer-Moore matcher to make this
bce86c4163a3 Initial revision
kono
parents:
diff changeset
516 * check relatively cheap. The first "if" figures
bce86c4163a3 Initial revision
kono
parents:
diff changeset
517 * out what position in the pattern matches the last
bce86c4163a3 Initial revision
kono
parents:
diff changeset
518 * character in the buffer. The inner "while" matches
bce86c4163a3 Initial revision
kono
parents:
diff changeset
519 * the pattern against the buffer, backwards starting
bce86c4163a3 Initial revision
kono
parents:
diff changeset
520 * at that position. Note that unless the buffer
bce86c4163a3 Initial revision
kono
parents:
diff changeset
521 * ends with one of the characters in the pattern
bce86c4163a3 Initial revision
kono
parents:
diff changeset
522 * (excluding the first and last), we do only one test.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
523 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
524 ep = bp + c - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
525 if (sp = pat_map[*ep & 0x00ff]) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
526 do {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
527 cp = sp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
528 while (*--ep == *--cp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
529 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
530 if (cp < fdelim) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
531 if (ep >= bp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
532 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
533 * ep < bp means that all the buffer
bce86c4163a3 Initial revision
kono
parents:
diff changeset
534 * contains is a prefix of delim.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
535 * If this prefix is really a delim, the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
536 * m_eom call at entry should have found
bce86c4163a3 Initial revision
kono
parents:
diff changeset
537 * it. Thus it's not a delim and we can
bce86c4163a3 Initial revision
kono
parents:
diff changeset
538 * take all of it.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
539 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
540 c = (ep - bp) + 2;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
541 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
542 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
543 /* try matching one less char of delim string */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
544 ep = bp + c - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
545 } while (--sp > fdelim);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
546 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
547 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
548 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
549 (void) bcopy( bp, buf, c );
bce86c4163a3 Initial revision
kono
parents:
diff changeset
550 #ifdef _STDIO_USES_IOSTREAM
bce86c4163a3 Initial revision
kono
parents:
diff changeset
551 iob->_IO_read_ptr += c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
552 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
553 iob->_cnt -= c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
554 iob->_ptr += c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
555 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
556 if (bufsz < 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
557 msg_count = c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
558 return (state);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
559 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
560 cp = buf + c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
561 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
562
bce86c4163a3 Initial revision
kono
parents:
diff changeset
563 default:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
564 adios (NULLCP, "m_getfld() called with bogus state of %d", state);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
565 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
566 finish:;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
567 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
568 msg_count = cp - buf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
569
bce86c4163a3 Initial revision
kono
parents:
diff changeset
570 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
571 /* Check whether this was a Content-Length header */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
572 if (msg_style == MS_UUCP && state == FLD &&
bce86c4163a3 Initial revision
kono
parents:
diff changeset
573 uleq((char*)"content-length", (char*) name)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
574 content_length = atoi(buf);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
575 /* This value is computed when end-of-headers is detected */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
576 end_of_contents = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
577 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
578 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
579 return (state);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
580 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
581
bce86c4163a3 Initial revision
kono
parents:
diff changeset
582 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
583
bce86c4163a3 Initial revision
kono
parents:
diff changeset
584 #ifdef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
585 static char unixbuf[BUFSIZ] = "";
bce86c4163a3 Initial revision
kono
parents:
diff changeset
586 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
587
bce86c4163a3 Initial revision
kono
parents:
diff changeset
588 void
bce86c4163a3 Initial revision
kono
parents:
diff changeset
589 m_unknown(iob)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
590 register FILE *iob;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
591 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
592 register int c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
593 register long pos;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
594 char text[10];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
595 register char *cp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
596 register char *delimstr;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
597
bce86c4163a3 Initial revision
kono
parents:
diff changeset
598 msg_style = MS_UNKNOWN;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
599
bce86c4163a3 Initial revision
kono
parents:
diff changeset
600 /* Figure out what the message delimitter string is for this
bce86c4163a3 Initial revision
kono
parents:
diff changeset
601 * maildrop. (This used to be part of m_Eom but I didn't like
bce86c4163a3 Initial revision
kono
parents:
diff changeset
602 * the idea of an "if" statement that could only succeed on the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
603 * first call to m_Eom getting executed on each call, i.e., at
bce86c4163a3 Initial revision
kono
parents:
diff changeset
604 * every newline in the message).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
605 *
bce86c4163a3 Initial revision
kono
parents:
diff changeset
606 * If the first line of the maildrop is a Unix "from" line, we say the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
607 * style is UUCP and eat the rest of the line. Otherwise we say the style
bce86c4163a3 Initial revision
kono
parents:
diff changeset
608 * is MMDF & look for the delimiter string specified when MH was built
bce86c4163a3 Initial revision
kono
parents:
diff changeset
609 * (or from the mtstailor file).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
610 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
611 pos = ftell (iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
612 if (fread (text, sizeof *text, 5, iob) == 5
bce86c4163a3 Initial revision
kono
parents:
diff changeset
613 && strncmp (text, "From ", 5) == 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
614 msg_style = MS_UUCP;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
615 delimstr = "\nFrom ";
bce86c4163a3 Initial revision
kono
parents:
diff changeset
616 #ifndef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
617 while ((c = getc (iob)) != '\n' && c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
618 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
619 #else /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
620 cp = unixbuf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
621 while ((c = getc (iob)) != '\n')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
622 *cp++ = c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
623 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
624 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
625 } else {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
626 /* not a Unix style maildrop */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
627 (void) fseek (iob, pos, 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
628 if (mmdlm2 == NULLCP || *mmdlm2 == 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
629 mmdlm2 = "\001\001\001\001\n";
bce86c4163a3 Initial revision
kono
parents:
diff changeset
630 delimstr = mmdlm2;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
631 msg_style = MS_MMDF;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
632 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
633 c = strlen (delimstr);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
634 fdelim = (unsigned char *)malloc((unsigned)c + 3);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
635 *fdelim++ = '\0';
bce86c4163a3 Initial revision
kono
parents:
diff changeset
636 *fdelim = '\n';
bce86c4163a3 Initial revision
kono
parents:
diff changeset
637 msg_delim = (char *)fdelim+1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
638 edelim = (unsigned char *)msg_delim+1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
639 fdelimlen = c + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
640 edelimlen = c - 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
641 (void)strcpy(msg_delim, delimstr);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
642 delimend = (unsigned char *)msg_delim + edelimlen;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
643 if (edelimlen <= 1)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
644 adios (NULLCP, "maildrop delimiter must be at least 2 bytes");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
645 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
646 * build a Boyer-Moore end-position map for the matcher in m_getfld.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
647 * N.B. - we don't match just the first char (since it's the newline
bce86c4163a3 Initial revision
kono
parents:
diff changeset
648 * separator) or the last char (since the matchc would have found it
bce86c4163a3 Initial revision
kono
parents:
diff changeset
649 * if it was a real delim).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
650 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
651 pat_map = (unsigned char **) calloc (256, sizeof (unsigned char *));
bce86c4163a3 Initial revision
kono
parents:
diff changeset
652
bce86c4163a3 Initial revision
kono
parents:
diff changeset
653 for (cp = (char *)fdelim + 1; cp < (char *)delimend; cp++ )
bce86c4163a3 Initial revision
kono
parents:
diff changeset
654 pat_map[*cp] = (unsigned char *)cp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
655
bce86c4163a3 Initial revision
kono
parents:
diff changeset
656 if (msg_style == MS_MMDF) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
657 /* flush extra msg hdrs */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
658 while ((c = Getc(iob)) >= 0 && eom (c, iob))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
659 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
660 if (c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
661 (void) ungetc(c, iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
662 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
663 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
664
bce86c4163a3 Initial revision
kono
parents:
diff changeset
665
bce86c4163a3 Initial revision
kono
parents:
diff changeset
666 void m_eomsbr (action)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
667 int (*action) ();
bce86c4163a3 Initial revision
kono
parents:
diff changeset
668 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
669 if (eom_action = action) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
670 msg_style = MS_MSH;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
671 *msg_delim = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
672 fdelimlen = 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
673 delimend = fdelim;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
674 } else {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
675 msg_style = MS_MMDF;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
676 msg_delim = (char *)fdelim + 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
677 fdelimlen = strlen((char *)fdelim);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
678 delimend = (unsigned char *)(msg_delim + edelimlen);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
679 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
680 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
681
bce86c4163a3 Initial revision
kono
parents:
diff changeset
682 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
683
bce86c4163a3 Initial revision
kono
parents:
diff changeset
684 /* test for msg delimiter string */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
685
bce86c4163a3 Initial revision
kono
parents:
diff changeset
686 int m_Eom (c, iob)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
687 register int c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
688 register FILE *iob;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
689 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
690 register long pos = 0L;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
691 register int i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
692 char text[10];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
693 #ifdef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
694 register char *cp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
695 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
696
bce86c4163a3 Initial revision
kono
parents:
diff changeset
697 pos = ftell (iob);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
698
bce86c4163a3 Initial revision
kono
parents:
diff changeset
699 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
700 if (msg_style == MS_UUCP && end_of_contents != -1) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
701 if (end_of_contents == pos) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
702 end_of_contents = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
703 if ((fread (text, sizeof *text, edelimlen, iob) == edelimlen)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
704 && (strncmp (text, (char *)edelim, edelimlen) == 0)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
705 #ifndef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
706 while ((c = getc (iob)) != '\n')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
707 if (c < 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
708 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
709 #else /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
710 cp = unixbuf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
711 while ((c = getc (iob)) != '\n' && c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
712 *cp++ = c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
713 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
714 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
715 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
716 return 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
717 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
718 /* we've read past the end of a message, this should never happen
bce86c4163a3 Initial revision
kono
parents:
diff changeset
719 * because of the other checks we do */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
720 if (end_of_contents < pos) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
721 end_of_contents = -1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
722 adios(NULLCP,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
723 "Content-Length: header broken, can't read mailbox\n");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
724 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
725 return 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
726 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
727 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
728
bce86c4163a3 Initial revision
kono
parents:
diff changeset
729 if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen
bce86c4163a3 Initial revision
kono
parents:
diff changeset
730 || strncmp (text, (char *)edelim, edelimlen)) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
731 if (i == 0 && msg_style == MS_UUCP)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
732 /* the final newline in the (brain damaged) unix-format
bce86c4163a3 Initial revision
kono
parents:
diff changeset
733 * maildrop is part of the delimitter - delete it.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
734 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
735 return 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
736
bce86c4163a3 Initial revision
kono
parents:
diff changeset
737 #ifdef notdef
bce86c4163a3 Initial revision
kono
parents:
diff changeset
738 (void) fseek (iob, pos, 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
739 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
740 (void) fseek (iob, (long)(pos-1), 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
741 (void) getc (iob); /* should be OK */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
742 #endif /* !notdef */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
743 return 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
744 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
745
bce86c4163a3 Initial revision
kono
parents:
diff changeset
746 #ifdef CONTENT_LENGTH
bce86c4163a3 Initial revision
kono
parents:
diff changeset
747 /* There's one extra special case to be considered here:
bce86c4163a3 Initial revision
kono
parents:
diff changeset
748 * content_length > 0. That we got here is because the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
749 * message body starts with "From "
bce86c4163a3 Initial revision
kono
parents:
diff changeset
750 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
751 if (msg_style == MS_UUCP && content_length > 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
752 (void) fseek (iob, (long)(pos-1), 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
753 (void) getc (iob); /* should be OK */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
754 return 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
755 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
756 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
757
bce86c4163a3 Initial revision
kono
parents:
diff changeset
758 if (msg_style == MS_UUCP) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
759 #ifndef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
760 while ((c = getc (iob)) != '\n')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
761 if (c < 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
762 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
763 #else /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
764 cp = unixbuf;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
765 while ((c = getc (iob)) != '\n' && c >= 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
766 *cp++ = c;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
767 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
768 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
769 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
770
bce86c4163a3 Initial revision
kono
parents:
diff changeset
771 return 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
772 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
773
bce86c4163a3 Initial revision
kono
parents:
diff changeset
774 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
775
bce86c4163a3 Initial revision
kono
parents:
diff changeset
776 #ifdef RPATHS
bce86c4163a3 Initial revision
kono
parents:
diff changeset
777 char *unixline () {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
778 register char *cp,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
779 *dp,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
780 *pp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
781 static char unixfrom[BUFSIZ];
bce86c4163a3 Initial revision
kono
parents:
diff changeset
782 int i;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
783
bce86c4163a3 Initial revision
kono
parents:
diff changeset
784 pp = unixfrom;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
785 if (cp = dp = index (unixbuf, ' ')) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
786 while (cp = index (cp + 1, 'r'))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
787 if (strncmp (cp, "remote from ", 12) == 0) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
788 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
789 (void) sprintf (pp, "%s!", cp + 12);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
790 pp += strlen (pp);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
791 break;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
792 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
793 if (cp == NULL)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
794 cp = unixbuf + strlen (unixbuf);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
795 #if 0
bce86c4163a3 Initial revision
kono
parents:
diff changeset
796 if ((cp -= 25) >= dp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
797 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
798 /* On most of BSD systems, the date field length of UNIX From line
bce86c4163a3 Initial revision
kono
parents:
diff changeset
799 is 25, but it's not suitable for other systems. We should not
bce86c4163a3 Initial revision
kono
parents:
diff changeset
800 use this length. */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
801 while (cp > dp && *--cp != ':')
bce86c4163a3 Initial revision
kono
parents:
diff changeset
802 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
803 for (i = 0; i < 4 && cp > dp; i++) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
804 while (!isspace(*--cp))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
805 ;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
806 while (isspace(*(cp - 1)))
bce86c4163a3 Initial revision
kono
parents:
diff changeset
807 --cp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
808 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
809 if (cp >= dp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
810 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
811 *cp = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
812 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
813
bce86c4163a3 Initial revision
kono
parents:
diff changeset
814 (void) sprintf (pp, "%s\n", unixbuf);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
815 unixbuf[0] = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
816 return unixfrom;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
817 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
818 #endif /* RPATHS */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
819
bce86c4163a3 Initial revision
kono
parents:
diff changeset
820 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
821
bce86c4163a3 Initial revision
kono
parents:
diff changeset
822 /* matchc: find the first occurrence of string pat in string str.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
823 * We can't use the C library routine strstr because the string
bce86c4163a3 Initial revision
kono
parents:
diff changeset
824 * won't have a trailing NUL. See also the note about using a
bce86c4163a3 Initial revision
kono
parents:
diff changeset
825 * Boyer-Moore search on non-Vaxen (in the only place this fn
bce86c4163a3 Initial revision
kono
parents:
diff changeset
826 * is used...)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
827 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
828 #if (vax && !lint)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
829 asm(".align 1");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
830 asm("_matchc: .word 0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
831 asm(" movq 4(ap),r0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
832 asm(" movq 12(ap),r2");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
833 asm(" matchc r0,(r1),r2,(r3)");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
834 asm(" beql 1f");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
835 asm(" movl 4(ap),r3");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
836 asm("1: subl3 4(ap),r3,r0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
837 asm(" ret");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
838 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
839 static unsigned char *
bce86c4163a3 Initial revision
kono
parents:
diff changeset
840 matchc( patln, pat, strln, str )
bce86c4163a3 Initial revision
kono
parents:
diff changeset
841 int patln;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
842 char *pat;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
843 int strln;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
844 register char *str;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
845 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
846 register char *es = str + strln - patln;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
847 register char *sp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
848 register char *pp;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
849 register char *ep = pat + patln;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
850 register char pc = *pat++;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
851
bce86c4163a3 Initial revision
kono
parents:
diff changeset
852 /* es is a pointer to the last character we need to
bce86c4163a3 Initial revision
kono
parents:
diff changeset
853 * check (the pattern can't start beyond it because then
bce86c4163a3 Initial revision
kono
parents:
diff changeset
854 * the end of the pattern would be beyond the end of the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
855 * string).
bce86c4163a3 Initial revision
kono
parents:
diff changeset
856 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
857 for(;;) {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
858 /* Search for the next occurrence of pc (first character
bce86c4163a3 Initial revision
kono
parents:
diff changeset
859 * in the pattern.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
860 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
861 do {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
862 if (str > es)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
863 return 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
864 } while (pc != *str++);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
865
bce86c4163a3 Initial revision
kono
parents:
diff changeset
866 /* At this point we have a match for the first
bce86c4163a3 Initial revision
kono
parents:
diff changeset
867 * character and basically do a strcmp() for the
bce86c4163a3 Initial revision
kono
parents:
diff changeset
868 * rest of the pattern. We know that the pattern
bce86c4163a3 Initial revision
kono
parents:
diff changeset
869 * will fit in the remainder of the string because
bce86c4163a3 Initial revision
kono
parents:
diff changeset
870 * of the es check.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
871 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
872 sp = str; pp = pat;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
873 while (pp < ep && *sp++ == *pp)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
874 pp++;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
875
bce86c4163a3 Initial revision
kono
parents:
diff changeset
876 if (pp >= ep) /* whole pattern matched? */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
877 return ((unsigned char *)--str);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
878
bce86c4163a3 Initial revision
kono
parents:
diff changeset
879 /* If we get this far then it wasn't a good match,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
880 * so go back to looking for the first character in
bce86c4163a3 Initial revision
kono
parents:
diff changeset
881 * the pattern.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
882 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
883
bce86c4163a3 Initial revision
kono
parents:
diff changeset
884 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
885 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
886 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
887
bce86c4163a3 Initial revision
kono
parents:
diff changeset
888 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
889
bce86c4163a3 Initial revision
kono
parents:
diff changeset
890 /*
bce86c4163a3 Initial revision
kono
parents:
diff changeset
891 * Locate character "term" in the next "cnt" characters of "src".
bce86c4163a3 Initial revision
kono
parents:
diff changeset
892 * If found, return its address, otherwise return 0.
bce86c4163a3 Initial revision
kono
parents:
diff changeset
893 */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
894 #if (vax && !lint)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
895 asm(".align 1");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
896 asm("_locc: .word 0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
897 asm(" movq 4(ap),r0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
898 asm(" locc 12(ap),r0,(r1)");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
899 asm(" beql 1f");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
900 asm(" movl r1,r0");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
901 asm("1: ret");
bce86c4163a3 Initial revision
kono
parents:
diff changeset
902 #else
bce86c4163a3 Initial revision
kono
parents:
diff changeset
903 static unsigned char *
bce86c4163a3 Initial revision
kono
parents:
diff changeset
904 locc( cnt, src, term )
bce86c4163a3 Initial revision
kono
parents:
diff changeset
905 register int cnt;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
906 register unsigned char *src;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
907 register unsigned char term;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
908 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
909 while (*src++ != term && --cnt > 0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
910
bce86c4163a3 Initial revision
kono
parents:
diff changeset
911 return (cnt > 0 ? --src : (unsigned char *)0);
bce86c4163a3 Initial revision
kono
parents:
diff changeset
912 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
913 #endif
bce86c4163a3 Initial revision
kono
parents:
diff changeset
914
bce86c4163a3 Initial revision
kono
parents:
diff changeset
915 /* */
bce86c4163a3 Initial revision
kono
parents:
diff changeset
916
bce86c4163a3 Initial revision
kono
parents:
diff changeset
917 #if !defined (BSD42) && !defined (bcopy)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
918 int bcmp (b1, b2, length)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
919 register char *b1,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
920 *b2;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
921 register int length;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
922 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
923 while (length-- > 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
924 if (*b1++ != *b2++)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
925 return 1;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
926
bce86c4163a3 Initial revision
kono
parents:
diff changeset
927 return 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
928 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
929
bce86c4163a3 Initial revision
kono
parents:
diff changeset
930
bce86c4163a3 Initial revision
kono
parents:
diff changeset
931 bcopy (b1, b2, length)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
932 register char *b1,
bce86c4163a3 Initial revision
kono
parents:
diff changeset
933 *b2;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
934 register int length;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
935 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
936 while (length-- > 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
937 *b2++ = *b1++;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
938 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
939
bce86c4163a3 Initial revision
kono
parents:
diff changeset
940
bce86c4163a3 Initial revision
kono
parents:
diff changeset
941 bzero (b, length)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
942 register char *b;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
943 register int length;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
944 {
bce86c4163a3 Initial revision
kono
parents:
diff changeset
945 while (length-- > 0)
bce86c4163a3 Initial revision
kono
parents:
diff changeset
946 *b++ = 0;
bce86c4163a3 Initial revision
kono
parents:
diff changeset
947 }
bce86c4163a3 Initial revision
kono
parents:
diff changeset
948 #endif /* not BSD42 */