Added all of the MH sources, including RCS files, in
[mmh] / 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 @