]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/RCS/scansbr.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / RCS / scansbr.c,v
1 head 1.16;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.16
9 date 94.04.21.18.20.50; author jromine; state Exp;
10 branches;
11 next 1.15;
12
13 1.15
14 date 93.08.20.15.54.08; author jromine; state Exp;
15 branches;
16 next 1.14;
17
18 1.14
19 date 93.02.26.22.00.09; author jromine; state Exp;
20 branches;
21 next 1.13;
22
23 1.13
24 date 92.12.15.00.20.22; author jromine; state Exp;
25 branches;
26 next 1.12;
27
28 1.12
29 date 92.02.18.17.44.05; author jromine; state Exp;
30 branches;
31 next 1.11;
32
33 1.11
34 date 92.02.15.01.02.18; author jromine; state Exp;
35 branches;
36 next 1.10;
37
38 1.10
39 date 92.02.10.19.21.00; author jromine; state Exp;
40 branches;
41 next 1.9;
42
43 1.9
44 date 92.02.05.07.26.30; author jromine; state Exp;
45 branches;
46 next 1.8;
47
48 1.8
49 date 92.01.31.22.26.36; author jromine; state Exp;
50 branches;
51 next 1.7;
52
53 1.7
54 date 92.01.30.00.11.23; author jromine; state Exp;
55 branches;
56 next 1.6;
57
58 1.6
59 date 92.01.23.23.06.45; author jromine; state Exp;
60 branches;
61 next 1.5;
62
63 1.5
64 date 90.04.05.14.57.59; author sources; state Exp;
65 branches;
66 next 1.4;
67
68 1.4
69 date 90.03.17.09.53.37; author sources; state Exp;
70 branches;
71 next 1.3;
72
73 1.3
74 date 90.02.09.10.50.25; author sources; state Exp;
75 branches;
76 next 1.2;
77
78 1.2
79 date 90.02.06.16.40.46; author sources; state Exp;
80 branches;
81 next 1.1;
82
83 1.1
84 date 90.02.06.16.37.35; author sources; state Exp;
85 branches;
86 next ;
87
88
89 desc
90 @@
91
92
93 1.16
94 log
95 @update for scansbr.c -- overload {folder}.c_flags with hdrflg
96 @
97 text
98 @/* scansbr.c - routines to help scan along... */
99 #ifndef lint
100 static char ident[] = "@@(#)$Id: scansbr.c,v 1.15 1993/08/20 15:54:08 jromine Exp jromine $";
101 #endif /* lint */
102
103 #include "../h/mh.h"
104 #include "../h/addrsbr.h"
105 #include "../h/formatsbr.h"
106 #include "../h/scansbr.h"
107 #include "../zotnet/tws.h"
108 #include <stdio.h>
109 #include <ctype.h>
110 #include <sys/types.h>
111 #include <sys/stat.h>
112
113 #ifdef _FSTDIO
114 #define _ptr _p /* Gag */
115 #define _cnt _w /* Wretch */
116 #endif
117
118 #define MAXSCANL 256 /* longest possible scan line */
119 #define SBUFSIZ 512 /* buffer size for content part of header
120 * fields. We want this to be large
121 * enough so that we don't do a lot of
122 * extra FLDPLUS calls on m_getfld but
123 * small enough so that we don't snarf
124 * the entire message body when we're
125 * only going to display 30 characters
126 * of it.
127 */
128
129 /* \f */
130
131 static struct format *fmt;
132 #ifdef JLR
133 static struct format *fmt_top;
134 #endif /* JLR */
135
136 static struct comp *datecomp; /* pntr to "date" comp */
137 static struct comp *bodycomp; /* pntr to "body" pseudo-comp
138 * (if referenced) */
139 static int ncomps = 0; /* # of interesting components */
140 static char **compbuffers = 0; /* buffers for component text */
141 static struct comp **used_buf = 0; /* stack for comp that use buffers */
142
143 char *scanl = 0; /* text of most recent scanline */
144
145 static int dat[5]; /* aux. data for format routine */
146
147 #ifdef RPATHS
148 char *unixline (); /* info from UNIX From: line */
149 #endif /* RPATHS */
150
151 #define FPUTS(buf) {\
152 if (mh_fputs(buf,scnout) == EOF)\
153 adios (scnmsg, "write error on");\
154 }
155
156 /* \f */
157
158 /* ARGSUSED */
159
160 int scan (inb, innum, outnum, nfs, width, curflg, unseen,
161 hdrflg, folder, size, noisy)
162 char *nfs,
163 *folder;
164 int innum,
165 outnum,
166 width,
167 curflg,
168 unseen,
169 hdrflg,
170 noisy;
171 long size;
172 register FILE *inb;
173 {
174 int compnum,
175 encrypted,
176 state;
177 register int i;
178 register char *cp;
179 register struct comp *cptr;
180 register char *tmpbuf;
181 register char **nxtbuf;
182 register struct comp **savecomp;
183 char *scnmsg;
184 FILE *scnout;
185 char name[NAMESZ];
186 static int rlwidth,
187 slwidth;
188
189 /* first-time only initialization */
190 if (scanl == NULLCP) {
191 int bigwid;
192
193 if (width == 0) {
194 if ((width = sc_width ()) < WIDTH/2)
195 width = WIDTH/2;
196 else if (width > MAXSCANL)
197 width = MAXSCANL;
198 }
199 dat[3] = slwidth = width;
200 if ((scanl = (char *)malloc( (unsigned) (slwidth + 2) )) == (char *)0)
201 adios (NULLCP, "unable to malloc scan line (%d bytes)", slwidth+2);
202 if (outnum)
203 (void) umask( ~ m_gmprot() );
204
205 ncomps = fmt_compile (nfs, &fmt) + 1;
206 #ifdef JLR
207 fmt_top = fmt;
208 #endif /* JLR */
209 FINDCOMP(bodycomp, "body");
210 FINDCOMP(datecomp, "date");
211 FINDCOMP(cptr, "folder");
212 if (cptr && folder) {
213 cptr->c_text = folder;
214 cptr->c_flags = hdrflg;
215 }
216 FINDCOMP(cptr, "encrypted");
217 if (!cptr)
218 if (cptr = (struct comp *) calloc (1, sizeof *cptr)) {
219 cptr -> c_name = "encrypted";
220 cptr -> c_next = wantcomp[i = CHASH (cptr -> c_name)];
221 wantcomp[i] = cptr;
222 ncomps++;
223 }
224 FINDCOMP (cptr, "dtimenow");
225 if (cptr)
226 cptr->c_text = getcpy(dtimenow ());
227 nxtbuf = compbuffers = (char **)calloc((unsigned) ncomps,
228 sizeof(char *));
229 if (nxtbuf == NULL)
230 adios (NULLCP, "unable to allocate component buffers");
231 used_buf = (struct comp **)calloc((unsigned) (ncomps+1),
232 sizeof(struct comp *));
233 if (used_buf == NULL)
234 adios (NULLCP, "unable to allocate component buffer stack");
235 used_buf += ncomps+1; *--used_buf = 0;
236 rlwidth = bodycomp && (width > SBUFSIZ) ? width : SBUFSIZ;
237 for (i = ncomps; i--; )
238 if ((*nxtbuf++ = malloc( rlwidth )) == NULL)
239 adios (NULLCP, "unable to allocate component buffer");
240 }
241 /* each-message initialization */
242 nxtbuf = compbuffers;
243 savecomp = used_buf;
244 tmpbuf = *nxtbuf++;
245 dat[0] = innum ? innum : outnum;
246 dat[1] = curflg;
247 dat[4] = unseen;
248
249 /*
250 * get the first field. If the msg is non-empty and we're doing
251 * an "inc", open the output file.
252 */
253 if ((state = m_getfld (FLD, name, tmpbuf, rlwidth, inb)) == FILEEOF)
254 if (ferror(inb)) {
255 advise("read", "unable to"); /* "read error" */
256 return SCNFAT;
257 } else
258 return SCNEOF;
259
260 if (outnum) {
261 if (outnum > 0) { /* Fix from Van -- I'm not sure why... */
262 scnmsg = m_name (outnum);
263 if (*scnmsg == '?') /* msg num out of range */
264 return SCNNUM;
265 }
266 else
267 scnmsg = "/dev/null";
268 if ((scnout = fopen (scnmsg, "w")) == NULL)
269 adios (scnmsg, "unable to write");
270 #ifdef RPATHS
271 if ((cp = unixline ()) && *cp != '\n') {
272 FPUTS ("Return-Path: ");
273 FPUTS (cp);
274 }
275 #endif /* RPATHS */
276 }
277
278 /* scan - main loop */
279 for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, rlwidth, inb)) {
280 switch (state) {
281 case FLD:
282 case FLDPLUS:
283 compnum++;
284 if (outnum) {
285 FPUTS (name);
286 (void) putc (':', scnout);
287 FPUTS (tmpbuf);
288 }
289 /*
290 * if we're interested in this component, save a pointer
291 * to the component text, then start using our next free
292 * buffer as the component temp buffer (buffer switching
293 * saves an extra copy of the component text).
294 */
295 if (cptr = wantcomp[CHASH(name)])
296 do {
297 if (uleq(name, cptr->c_name)) {
298 if (! cptr->c_text) {
299 cptr->c_text = tmpbuf;
300 for (cp = tmpbuf + strlen (tmpbuf) - 1;
301 cp >= tmpbuf; cp--)
302 if (isspace (*cp))
303 *cp = 0;
304 else
305 break;
306 *--savecomp = cptr;
307 tmpbuf = *nxtbuf++;
308 }
309 break;
310 }
311 } while (cptr = cptr->c_next);
312
313 while (state == FLDPLUS) {
314 state = m_getfld (state, name, tmpbuf, rlwidth, inb);
315 if (outnum)
316 FPUTS (tmpbuf);
317 }
318 break;
319
320 case BODY:
321 compnum = -1;
322 if (! outnum) {
323 state = FILEEOF; /* stop now if scan cmd */
324 goto finished;
325 }
326 (void) putc ('\n', scnout);
327 FPUTS (tmpbuf);
328 /*
329 * performance hack: some people like to run "inc" on
330 * things like net.sources or large digests. We do a
331 * copy directly into the output buffer rather than
332 * going through an intermediate buffer.
333 *
334 * We need the amount of data m_getfld found & don't
335 * want to do a strlen on the long buffer so there's
336 * a hack in m_getfld to save the amount of data it
337 * returned in the global "msg_count".
338 */
339 body: ;
340 while (state == BODY) {
341 if (scnout->_cnt <= 0) {
342 if (fflush(scnout) == EOF)
343 adios (scnmsg, "write error on");
344 }
345 state = m_getfld( state, name, scnout->_ptr,
346 -(scnout->_cnt), inb );
347 scnout->_cnt -= msg_count;
348 scnout->_ptr += msg_count;
349 }
350 goto finished;
351
352 case LENERR:
353 case FMTERR:
354 fprintf (stderr,
355 innum ? "??Format error (message %d) in "
356 : "??Format error in ",
357 outnum ? outnum : innum);
358 fprintf (stderr, "component %d\n", compnum);
359
360 if (outnum) {
361 FPUTS ("\n\nBAD MSG:\n");
362 FPUTS (name);
363 (void) putc ('\n', scnout);
364 state = BODY;
365 goto body;
366 }
367 /* fall through */
368
369 case FILEEOF:
370 goto finished;
371
372 default:
373 adios (NULLCP, "getfld() returned %d", state);
374 }
375 }
376 /*
377 * format and output the scan line.
378 */
379 finished:
380 if (ferror(inb)) {
381 advise("read", "unable to"); /* "read error" */
382 return SCNFAT;
383 }
384 {
385 char *saved_c_text;
386
387 if (bodycomp) {
388 /* Save and restore buffer so we don't trash our dynamic pool! */
389 saved_c_text = bodycomp->c_text;
390 bodycomp->c_text = tmpbuf;
391 }
392
393 if (size)
394 dat[2] = size;
395 else if (outnum > 0)
396 dat[2] = ftell(scnout);
397
398 if ( (datecomp && ! datecomp->c_text) || (!size && !outnum)) {
399 struct stat st;
400 (void) fstat (fileno(inb), &st);
401 if (!size && !outnum)
402 dat[2] = st.st_size;
403 if (datecomp) {
404 if (! datecomp->c_text) {
405 if (datecomp->c_tws == NULL)
406 datecomp->c_tws = (struct tws *)
407 calloc((unsigned) 1, sizeof(*datecomp->c_tws));
408 if (datecomp->c_tws == NULL)
409 adios (NULLCP, "unable to allocate tws buffer");
410 *datecomp->c_tws = *dlocaltime ((long *) &st.st_mtime);
411 datecomp->c_flags = -1;
412 } else {
413 datecomp->c_flags = 0;
414 }
415 }
416 }
417 #ifndef JLR
418 (void) fmtscan (fmt, scanl, slwidth, dat);
419 #else /* JLR */
420 fmt = fmtscan (fmt, scanl, slwidth, dat);
421 if (!fmt)
422 fmt = fmt_top; /* reset for old format files */
423 #endif /* JLR */
424
425 if (bodycomp)
426 bodycomp->c_text = saved_c_text;
427 }
428 if (noisy)
429 (void) fputs (scanl, stdout);
430
431 FINDCOMP (cptr, "encrypted");
432 encrypted = cptr && cptr -> c_text;
433 /* return dynamically allocated buffers to pool */
434 while ( cptr = *savecomp++ ) {
435 *--nxtbuf = cptr->c_text;
436 cptr->c_text = NULLCP;
437 }
438 *--nxtbuf = tmpbuf;
439
440 if (outnum && fclose (scnout) == EOF)
441 adios (scnmsg, "write error on");
442
443 return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);
444 }
445
446 /* \f */
447
448 /* Cheat: we are loaded with adrparse, which wants a routine called
449 OfficialName(). We call adrparse:getm() with the correct arguments
450 to prevent OfficialName() from being called. Hence, the following
451 is to keep the loader happy.
452 */
453
454 char *OfficialName (name)
455 register char *name;
456 {
457 return name;
458 }
459
460 mh_fputs(s, stream)
461 char *s;
462 FILE *stream;
463 {
464 char c;
465 while(c = *s++)
466 if(putc(c,stream) == EOF )
467 return(EOF);
468 return(0);
469 }
470 @
471
472
473 1.15
474 log
475 @allow BIG widths
476 @
477 text
478 @d3 1
479 a3 1
480 static char ident[] = "@@(#)$Id: scansbr.c,v 1.14 1993/02/26 22:00:09 jromine Exp jromine $";
481 d63 2
482 a64 2
483 int scan (inb, innum, outnum, nfs, width, curflg,
484 unseen, folder, size, noisy)
485 d72 1
486 d115 1
487 a115 1
488 if (cptr && folder)
489 d117 2
490 @
491
492
493 1.14
494 log
495 @_FSTDIO
496 @
497 text
498 @d3 1
499 a3 1
500 static char ident[] = "@@(#)$Id: scansbr.c,v 1.13 1992/12/15 00:20:22 jromine Exp jromine $";
501 d88 2
502 a89 1
503 static int slwidth;
504 d93 2
505 d136 1
506 d138 1
507 a138 1
508 if ((*nxtbuf++ = malloc( SBUFSIZ )) == NULL)
509 d153 1
510 a153 1
511 if ((state = m_getfld (FLD, name, tmpbuf, SBUFSIZ, inb)) == FILEEOF)
512 d179 1
513 a179 1
514 for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb)) {
515 d214 1
516 a214 1
517 state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
518 @
519
520
521 1.13
522 log
523 @endif sugar
524 @
525 text
526 @d3 1
527 a3 1
528 static char ident[] = "@@(#)$Id: scansbr.c,v 1.12 1992/02/18 17:44:05 jromine Exp jromine $";
529 d16 4
530 @
531
532
533 1.12
534 log
535 @test malloc return
536 @
537 text
538 @d3 2
539 a4 2
540 static char ident[] = "@@(#)$Id: scansbr.c,v 1.11 1992/02/15 01:02:18 jromine Exp $";
541 #endif lint
542 d48 1
543 a48 1
544 #endif RPATHS
545 d103 1
546 a103 1
547 #endif JLR
548 d167 1
549 a167 1
550 #endif RPATHS
551 d311 1
552 a311 1
553 #else JLR
554 d315 1
555 a315 1
556 #endif JLR
557 @
558
559
560 1.11
561 log
562 @remove extra $Header$
563 @
564 text
565 @d3 1
566 a3 1
567 static char ident[] = "@@(#)$Id: scansbr.c,v 1.10 1992/02/10 19:21:00 jromine Exp jromine $";
568 d95 2
569 a96 1
570 scanl = (char *)malloc( (unsigned) (slwidth + 2) );
571 @
572
573
574 1.10
575 log
576 @report fatal errors
577 @
578 text
579 @d3 1
580 a3 1
581 static char ident[] = "@@(#)$Id: scansbr.c,v 1.9 1992/02/05 07:26:30 jromine Exp jromine $";
582 a4 1
583 static char *RCSid = "$Header: /usr/rand/src/bin/mh/uip/RCS/scansbr.c,v 1.3 91/02/05 14:10:35 pearlman Exp $";
584 @
585
586
587 1.9
588 log
589 @put unseen sequence in mh-format
590 @
591 text
592 @d3 1
593 a3 1
594 static char ident[] = "@@(#)$Id: scansbr.c,v 1.8 1992/01/31 22:26:36 jromine Exp jromine $";
595 d5 1
596 d146 5
597 a150 1
598 return SCNEOF;
599 d272 4
600 @
601
602
603 1.8
604 log
605 @kerberos
606 @
607 text
608 @d3 1
609 a3 1
610 static char ident[] = "@@(#)$Id: scansbr.c,v 1.7 1992/01/30 00:11:23 jromine Exp jromine $";
611 d44 1
612 a44 1
613 static int dat[4]; /* aux. data for format routine */
614 d59 2
615 a60 1
616 int scan (inb, innum, outnum, nfs, width, curflg, folder, size, noisy)
617 d67 1
618 d136 1
619 a136 1
620 dat[0] = innum? innum : outnum;
621 d138 1
622 @
623
624
625 1.7
626 log
627 @increase SBUFSIZ - some X.400 headers are pretty big!
628 @
629 text
630 @d3 1
631 a3 1
632 static char ident[] = "@@(#)$Id: scansbr.c,v 1.6 1992/01/23 23:06:45 jromine Exp jromine $";
633 d187 1
634 a187 1
635 *cp = NULL;
636 @
637
638
639 1.6
640 log
641 @new formatsbr changes under JLR
642 @
643 text
644 @d3 1
645 a3 1
646 static char ident[] = "@@(#)$Id: scansbr.c,v 1.5 1990/04/05 14:57:59 sources Exp jromine $";
647 d18 1
648 a18 1
649 #define SBUFSIZ 256 /* buffer size for content part of header
650 @
651
652
653 1.5
654 log
655 @add ID
656 @
657 text
658 @d3 1
659 a3 1
660 static char ident[] = "@@(#)$Id:$";
661 d31 3
662 d59 3
663 a61 2
664 int scan (inb, innum, outnum, nfs, width, curflg, header, size, noisy)
665 char *nfs;
666 a65 1
667 header,
668 d98 3
669 d103 3
670 d297 1
671 d299 5
672 @
673
674
675 1.4
676 log
677 @fixes from jeff honig
678 add {dtimenow} to scansbr
679 add a bunch of options to rcvtty
680 @
681 text
682 @d2 3
683 @
684
685
686 1.3
687 log
688 @Fixes from Van Jacobson
689 @
690 text
691 @d102 3
692 @
693
694
695 1.2
696 log
697 @build scan line even if not printing (for rcvtty, etc.)
698 @
699 text
700 @d15 1
701 a15 1
702 #define SBUFSIZ 128 /* buffer size for content part of header
703 d102 8
704 a109 2
705 nxtbuf = compbuffers = (char **)calloc((unsigned) ncomps,sizeof(char *));
706 used_buf = (struct comp **)calloc((unsigned) (ncomps+1),sizeof(struct comp *));
707 d112 2
708 a113 1
709 *nxtbuf++ = malloc( SBUFSIZ );
710 d130 7
711 a136 3
712 scnmsg = m_name (outnum);
713 if (*scnmsg == '?') /* msg num out of range */
714 return SCNNUM;
715 d140 1
716 a140 1
717 if ((cp = unixline ()) && *cp) {
718 d250 5
719 a254 1
720 if (bodycomp)
721 d256 1
722 d260 1
723 a260 1
724 else if (outnum)
725 d270 6
726 a275 3
727 struct tws dmt;
728 dmt = *dlocaltime ((long *) &st.st_mtime);
729 *datecomp->c_tws = dmt;
730 d285 1
731 a285 1
732 bodycomp->c_text = NULLCP;
733 @
734
735
736 1.1
737 log
738 @Initial revision
739 @
740 text
741 @d238 1
742 a238 1
743 if (noisy) {
744 a263 1
745 (void) fputs (scanl, stdout);
746 d268 2
747 @