]> diplodocus.org Git - nmh/blob - docs/historical/mh-nov-1983/cmds/scansub.c
Removed --depth 1 from git clone invocation.
[nmh] / docs / historical / mh-nov-1983 / cmds / scansub.c
1 #include "mh.h"
2 #include <stdio.h>
3
4 #define _FROM 1
5 #define _NOTFROM 0
6
7
8 #define FROM 13 /* Start of From field */
9 #define SFROM 16 /* Length of " " */
10 #define DATE 5 /* Start of Date field */
11 #define SDATE 7 /* Length */
12 #define SUBJ 31 /* Start of Subject field */
13 #define SSUBJ (79-SUBJ) /* Size of Subject field */
14 #define BSUBJ 20 /* Room needed in Sub field to */
15 /* add stuff from the body */
16 #define MSGN 0 /* Start of msg name field */
17 #define SMSGN 3 /* Length */
18 #define FLGS 3 /* Start of flags field */
19 #define SFLGS 2 /* Width of flag field */
20
21 FILE *scnout;
22 char scanl[82];
23 int local;
24 int hostseen;
25 char *frmtok();
26
27 scan(inb, innum, outnum, curflg)
28 struct iobuf *inb;
29 int outnum;
30 {
31
32 char buf[BUFSIZ], name[NAMESZ], tobuf[32], frombuf[32];
33 register char *cp, **tok1;
34 int state, subsz, first, compnum;
35 static char *myname;
36
37 local = 0; hostseen = 0;
38 if(!myname)
39 myname = getenv("USER");
40 tobuf[0] = 0; frombuf[0] = 0;
41 first = 0;
42 state = FLD;
43 compnum = 1;
44
45 for(;;) {
46
47 state = m_getfld(state, name, buf, sizeof buf, inb);
48 if(!first++ && state != FILEEOF) { /*##*/
49 if(outnum) {
50 if((scnout = fopen(cp = m_name(outnum), "w")) == NULL) {
51 fprintf(stderr, "Error creating msg ");
52 perror(cp); done(-1);
53 }
54 chmod(cp, m_gmprot());
55 }
56 sfill(scanl, sizeof scanl);
57 scanl[sizeof scanl - 1] = 0;
58 subsz = 0;
59 tobuf[0] = 0;
60 }
61
62 switch(state) {
63
64 case FLD:
65 case FLDEOF:
66 case FLDPLUS:
67 compnum++;
68 if(uleq(name, "from"))
69 frombuf[
70 cpyfrm(buf,frombuf,sizeof frombuf,_FROM)]=0;
71 else if(uleq(name, "date"))
72 cpydat(buf, scanl+DATE, SDATE);
73 else if(uleq(name, "subject") && scanl[SUBJ] == ' ')
74 subsz = cpy(buf, scanl+SUBJ, SSUBJ);
75 else if(uleq(name, "to") && !tobuf[0])
76 tobuf[
77 cpyfrm(buf,tobuf,sizeof tobuf-1,_NOTFROM)]=0;
78 else if(uleq(name, "replied"))
79 cpy("-", scanl+FLGS+1, 1);
80 put(name, buf, scnout);
81 while(state == FLDPLUS) {
82 state=m_getfld(state,name,buf,sizeof buf,inb);
83 if(scnout)
84 fputs(buf, scnout);
85 }
86 if(state == FLDEOF)
87 goto putscan;
88 continue;
89
90 case BODY:
91 case BODYEOF:
92 compnum = -1;
93 if(buf[0] && subsz < SSUBJ - BSUBJ) {
94 scanl[SUBJ+subsz+1] = '<';
95 scanl[SUBJ+subsz+2] = '<';
96 cpy(buf, scanl+SUBJ+subsz+3, SSUBJ-subsz-3);
97 subsz = SSUBJ;
98 }
99 if(buf[0] && scnout) {
100 putc('\n', scnout);
101 fputs(buf, scnout);
102 if(ferror(scnout)) {
103 fprintf(stderr, "Write error on ");
104 perror(m_name(outnum));done(-1);
105 }
106 }
107 body: while(state == BODY) {
108 state=m_getfld(state,name,buf,sizeof buf,inb);
109 if(scnout)
110 fputs(buf, scnout);
111 }
112 if(state == BODYEOF) {
113 putscan: cpymsgn(m_name(innum), scanl+MSGN, SMSGN);
114 tok1= brkstring(getcpy(frombuf), " ", "\n");
115 if(!frombuf[0] || uleq(frombuf, myname) ||
116 (local && uleq(*tok1, myname))) {
117 cpy("To:", scanl+FROM, 3);
118 cpy(tobuf, scanl+FROM+3, SFROM-3);
119 } else
120 cpy(frombuf, scanl+FROM, SFROM);
121 if(curflg)
122 cpy("+", scanl+FLGS, SFLGS);
123 trim(scanl);
124 fputs(scanl, stdout);
125
126 if(scnout) {
127 fflush(scnout);
128 if(ferror(scnout)) {
129 perror("Write error on ");
130 perror(m_name(outnum));
131 done(-1);
132 }
133 fclose(scnout);
134 scnout = NULL;
135 }
136 return(1);
137 }
138 break;
139
140 case LENERR:
141 case FMTERR:
142 fprintf(stderr, "??Message Format Error ");
143 fprintf(stderr, "(Message %d) ", outnum ? outnum :innum);/*##*/
144 if(compnum < 0) fprintf(stderr, "in the Body.\n");
145 else fprintf(stderr, "in Component #%d.\n", compnum);
146 fprintf(stderr, "-----------------------------------------");
147 fprintf(stderr, "-------------------------------------\n");
148 goto badret;
149 default:
150 fprintf(stderr, "Getfld returned %d\n", state);
151
152
153 badret: if(outnum) {
154 fputs("\n\nBAD MSG:\n", scnout);
155 if(compnum < 0)
156 fputs(buf, scnout);
157 else
158 fputs(name, scnout);
159 /*** ungetc(inb); ***/
160 state = BODY;
161 goto body;
162
163 }
164 if(scnout)
165 fflush(scnout);
166 return(-1);
167 case FILEEOF:
168 return(0);
169
170 }
171
172 }
173 }
174
175
176 trim(str)
177 char *str;
178 {
179 register char *cp;
180
181 cp = str;
182 while(*cp) cp++;
183 while(*--cp == ' ') ;
184 cp++;
185 *cp++ = '\n';
186 *cp++ = 0;
187 }
188
189 sfill(str, cnt)
190 char *str;
191 {
192 register char *cp;
193 register int i;
194
195 cp = str; i = cnt;
196 do
197 *cp++ = ' ';
198 while(--i);
199 }
200
201
202 put(name, buf, ip)
203 register FILE *ip;
204 {
205 if(ip) {
206 fputs(name, ip);
207 putc(':', ip);
208 fputs(buf, ip);
209 if(ferror(ip)) { perror("Write error");done(-1);}
210 }
211 }
212
213
214 cpy(from, to, cnt)
215 register char *from, *to;
216 register int cnt;
217 {
218 register int c;
219 char *sfrom;
220
221 sfrom = from;
222 while(*from == ' ' || *from == '\t' || *from == '\n')
223 from++;
224 while(cnt--)
225 if(c = *from) {
226 if(c == '\t' || c == ' ' || c == '\n') {
227 *to++ = ' ';
228 do
229 from++;
230 while((c= *from)==' '||c=='\t'||c=='\n');
231 continue;
232 } else
233 *to++ = c;
234 from++;
235 } else
236 break;
237 return(from - sfrom - 1);
238 }
239
240 int *localtime();
241 char *findmonth();
242
243 cpydat(sfrom, sto, cnt)
244 char *sfrom, *sto;
245 {
246 register char *from, *cp;
247 register int c;
248 static int *locvec;
249 long now;
250 char *to;
251
252 if(!locvec) {
253 time(&now);
254 locvec = localtime(&now);
255 }
256 to = sto;
257 for(from = sfrom; (c = *from) < '0' || c > '9'; from++)
258 if(!c)
259 return;
260 c = cnt;
261 for(cp = from; (*cp >= '0' && *cp <= '9') || *cp == ' '; cp++);
262 if(cp = findmonth(cp)) {
263 if(!cp[1]) {
264 *to++ = ' ';
265 c--;
266 }
267 while(*cp && c--)
268 *to++ = *cp++;
269 c--; *to++ = '/';
270 if(from[1] == ' ') {
271 *to++ = ' ';
272 c--;
273 }
274 while(*from >= '0' && *from <= '9' && c--)
275 *to++ = *from++;
276 if(c >= 2) {
277 while(*from < '0' || *from > '9') from++;
278 if(((c = atoi(from)) > 1970 && c-1900 < locvec[5])
279 || c < locvec[5]) {
280 *to++ = '/';
281 *to++ = (c < 100) ? (c - 70 + '0')
282 : (c - 1970 + '0');
283 }
284 }
285 return;
286 }
287 if(from[1] == ' ') {
288 *to++ = ' ';
289 c--;
290 }
291 while(*from && c--)
292 *to++ = *from++;
293 }
294
295
296 char *fromp, fromdlm, pfromdlm;
297
298 cpyfrm(sfrom, sto, cnt, fromcall)
299 char *sfrom, *sto;
300 {
301 register char *to, *cp;
302 register int c;
303
304 fromdlm = ' ';
305 fromp = sfrom; to = sto;
306 cp = frmtok();
307 do
308 if(c = *cp++)
309 *to++ = c;
310 else
311 break;
312 while(--cnt);
313 for(;;) {
314 if(cnt < 3) break;
315 if(*(cp = frmtok()) == 0) break;
316 if(*cp == '@' || uleq(cp, "at")) {
317 cp = frmtok();
318 if(uleq(cp, "berkeley")) {
319 /* if the first "From:" host is local */
320 if(fromcall && !hostseen++)
321 local++;
322 } else {
323 *to++ = '@';
324 cnt--;
325 do
326 if(c = *cp++)
327 *to++ = c;
328 else
329 break;
330 while(--cnt);
331 }
332 } else if(cnt > 4) {
333 cnt--; *to++ = pfromdlm;
334 do
335 if(c = *cp++)
336 *to++ = c;
337 else
338 break;
339 while(--cnt);
340 }
341 }
342 if(fromcall)
343 hostseen++;
344 return(to - sto);
345 }
346
347
348 char *frmtok()
349 {
350 static char tokbuf[64];
351 register char *cp;
352 register int c;
353
354 pfromdlm = fromdlm;
355 cp = tokbuf; *cp = 0;
356 while(c = *fromp++) {
357 if(c == '\t')
358 c = ' ';
359 if(c == ' ' && cp == tokbuf)
360 continue;
361 if(c == ' ' || c == '\n' || c == ',')
362 break;
363 *cp++ = c;
364 *cp = 0;
365 if(c == '@' || *fromp == '@' || cp == &tokbuf[63])
366 break;
367 }
368 fromdlm = c;
369 return(tokbuf);
370 }
371
372
373 /* num specific! */
374
375 cpymsgn(msgnam, addr, len)
376 char *msgnam, *addr;
377 {
378 register char *cp, *sp;
379
380 sp = msgnam;
381 cp = addr + (len - strlen(sp));
382 while(*sp)
383 *cp++ = *sp++;
384 }
385
386 char *monthtab[] = {
387 "jan", "feb", "mar", "apr", "may", "jun",
388 "jul", "aug", "sep", "oct", "nov", "dec",
389 };
390
391 char *findmonth(str)
392 char *str;
393 {
394 register char *cp, *sp;
395 register int i;
396 static char buf[4];
397 char *locv();
398
399 for(cp=str, sp=buf; (*sp++ = *cp++) && sp < &buf[3] && *cp != ' '; );
400 *sp = 0;
401 for(i = 0; i < 12; i++)
402 if(uleq(buf, monthtab[i])) {
403 sprintf(buf, "%2d", i+1);
404 return buf;
405 }
406 return(0);
407 }