9 date 94.04.21.18.20.50; author jromine; state Exp;
14 date 93.08.20.15.54.08; author jromine; state Exp;
19 date 93.02.26.22.00.09; author jromine; state Exp;
24 date 92.12.15.00.20.22; author jromine; state Exp;
29 date 92.02.18.17.44.05; author jromine; state Exp;
34 date 92.02.15.01.02.18; author jromine; state Exp;
39 date 92.02.10.19.21.00; author jromine; state Exp;
44 date 92.02.05.07.26.30; author jromine; state Exp;
49 date 92.01.31.22.26.36; author jromine; state Exp;
54 date 92.01.30.00.11.23; author jromine; state Exp;
59 date 92.01.23.23.06.45; author jromine; state Exp;
64 date 90.04.05.14.57.59; author sources; state Exp;
69 date 90.03.17.09.53.37; author sources; state Exp;
74 date 90.02.09.10.50.25; author sources; state Exp;
79 date 90.02.06.16.40.46; author sources; state Exp;
84 date 90.02.06.16.37.35; author sources; state Exp;
95 @update for scansbr.c -- overload {folder}.c_flags with hdrflg
98 @/* scansbr.c - routines to help scan along... */
100 static char ident[] = "@@(#)$Id: scansbr.c,v 1.15 1993/08/20 15:54:08 jromine Exp jromine $";
104 #include "../h/addrsbr.h"
105 #include "../h/formatsbr.h"
106 #include "../h/scansbr.h"
107 #include "../zotnet/tws.h"
110 #include <sys/types.h>
111 #include <sys/stat.h>
114 #define _ptr _p /* Gag */
115 #define _cnt _w /* Wretch */
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
131 static struct format *fmt;
133 static struct format *fmt_top;
136 static struct comp *datecomp; /* pntr to "date" comp */
137 static struct comp *bodycomp; /* pntr to "body" pseudo-comp
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 */
143 char *scanl = 0; /* text of most recent scanline */
145 static int dat[5]; /* aux. data for format routine */
148 char *unixline (); /* info from UNIX From: line */
151 #define FPUTS(buf) {\
152 if (mh_fputs(buf,scnout) == EOF)\
153 adios (scnmsg, "write error on");\
160 int scan (inb, innum, outnum, nfs, width, curflg, unseen,
161 hdrflg, folder, size, noisy)
179 register struct comp *cptr;
180 register char *tmpbuf;
181 register char **nxtbuf;
182 register struct comp **savecomp;
189 /* first-time only initialization */
190 if (scanl == NULLCP) {
194 if ((width = sc_width ()) < WIDTH/2)
196 else if (width > MAXSCANL)
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);
203 (void) umask( ~ m_gmprot() );
205 ncomps = fmt_compile (nfs, &fmt) + 1;
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;
216 FINDCOMP(cptr, "encrypted");
218 if (cptr = (struct comp *) calloc (1, sizeof *cptr)) {
219 cptr -> c_name = "encrypted";
220 cptr -> c_next = wantcomp[i = CHASH (cptr -> c_name)];
224 FINDCOMP (cptr, "dtimenow");
226 cptr->c_text = getcpy(dtimenow ());
227 nxtbuf = compbuffers = (char **)calloc((unsigned) ncomps,
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");
241 /* each-message initialization */
242 nxtbuf = compbuffers;
245 dat[0] = innum ? innum : outnum;
250 * get the first field. If the msg is non-empty and we're doing
251 * an "inc", open the output file.
253 if ((state = m_getfld (FLD, name, tmpbuf, rlwidth, inb)) == FILEEOF)
255 advise("read", "unable to"); /* "read error" */
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 */
267 scnmsg = "/dev/null";
268 if ((scnout = fopen (scnmsg, "w")) == NULL)
269 adios (scnmsg, "unable to write");
271 if ((cp = unixline ()) && *cp != '\n') {
272 FPUTS ("Return-Path: ");
278 /* scan - main loop */
279 for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, rlwidth, inb)) {
286 (void) putc (':', scnout);
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).
295 if (cptr = wantcomp[CHASH(name)])
297 if (uleq(name, cptr->c_name)) {
298 if (! cptr->c_text) {
299 cptr->c_text = tmpbuf;
300 for (cp = tmpbuf + strlen (tmpbuf) - 1;
311 } while (cptr = cptr->c_next);
313 while (state == FLDPLUS) {
314 state = m_getfld (state, name, tmpbuf, rlwidth, inb);
323 state = FILEEOF; /* stop now if scan cmd */
326 (void) putc ('\n', scnout);
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.
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".
340 while (state == BODY) {
341 if (scnout->_cnt <= 0) {
342 if (fflush(scnout) == EOF)
343 adios (scnmsg, "write error on");
345 state = m_getfld( state, name, scnout->_ptr,
346 -(scnout->_cnt), inb );
347 scnout->_cnt -= msg_count;
348 scnout->_ptr += msg_count;
355 innum ? "??Format error (message %d) in "
356 : "??Format error in ",
357 outnum ? outnum : innum);
358 fprintf (stderr, "component %d\n", compnum);
361 FPUTS ("\n\nBAD MSG:\n");
363 (void) putc ('\n', scnout);
373 adios (NULLCP, "getfld() returned %d", state);
377 * format and output the scan line.
381 advise("read", "unable to"); /* "read error" */
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;
396 dat[2] = ftell(scnout);
398 if ( (datecomp && ! datecomp->c_text) || (!size && !outnum)) {
400 (void) fstat (fileno(inb), &st);
401 if (!size && !outnum)
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;
413 datecomp->c_flags = 0;
418 (void) fmtscan (fmt, scanl, slwidth, dat);
420 fmt = fmtscan (fmt, scanl, slwidth, dat);
422 fmt = fmt_top; /* reset for old format files */
426 bodycomp->c_text = saved_c_text;
429 (void) fputs (scanl, stdout);
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;
440 if (outnum && fclose (scnout) == EOF)
441 adios (scnmsg, "write error on");
443 return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);
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.
454 char *OfficialName (name)
466 if(putc(c,stream) == EOF )
480 static char ident[] = "@@(#)$Id: scansbr.c,v 1.14 1993/02/26 22:00:09 jromine Exp jromine $";
483 int scan (inb, innum, outnum, nfs, width, curflg,
484 unseen, folder, size, noisy)
500 static char ident[] = "@@(#)$Id: scansbr.c,v 1.13 1992/12/15 00:20:22 jromine Exp jromine $";
508 if ((*nxtbuf++ = malloc( SBUFSIZ )) == NULL)
511 if ((state = m_getfld (FLD, name, tmpbuf, SBUFSIZ, inb)) == FILEEOF)
514 for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb)) {
517 state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
528 static char ident[] = "@@(#)$Id: scansbr.c,v 1.12 1992/02/18 17:44:05 jromine Exp jromine $";
540 static char ident[] = "@@(#)$Id: scansbr.c,v 1.11 1992/02/15 01:02:18 jromine Exp $";
562 @remove extra $Header$
567 static char ident[] = "@@(#)$Id: scansbr.c,v 1.10 1992/02/10 19:21:00 jromine Exp jromine $";
570 scanl = (char *)malloc( (unsigned) (slwidth + 2) );
581 static char ident[] = "@@(#)$Id: scansbr.c,v 1.9 1992/02/05 07:26:30 jromine Exp jromine $";
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 $";
589 @put unseen sequence in mh-format
594 static char ident[] = "@@(#)$Id: scansbr.c,v 1.8 1992/01/31 22:26:36 jromine Exp jromine $";
610 static char ident[] = "@@(#)$Id: scansbr.c,v 1.7 1992/01/30 00:11:23 jromine Exp jromine $";
613 static int dat[4]; /* aux. data for format routine */
616 int scan (inb, innum, outnum, nfs, width, curflg, folder, size, noisy)
620 dat[0] = innum? innum : outnum;
627 @increase SBUFSIZ - some X.400 headers are pretty big!
632 static char ident[] = "@@(#)$Id: scansbr.c,v 1.6 1992/01/23 23:06:45 jromine Exp jromine $";
641 @new formatsbr changes under JLR
646 static char ident[] = "@@(#)$Id: scansbr.c,v 1.5 1990/04/05 14:57:59 sources Exp jromine $";
649 #define SBUFSIZ 256 /* buffer size for content part of header
660 static char ident[] = "@@(#)$Id:$";
664 int scan (inb, innum, outnum, nfs, width, curflg, header, size, noisy)
677 @fixes from jeff honig
678 add {dtimenow} to scansbr
679 add a bunch of options to rcvtty
688 @Fixes from Van Jacobson
697 @build scan line even if not printing (for rcvtty, etc.)
702 #define SBUFSIZ 128 /* buffer size for content part of header
705 nxtbuf = compbuffers = (char **)calloc((unsigned) ncomps,sizeof(char *));
706 used_buf = (struct comp **)calloc((unsigned) (ncomps+1),sizeof(struct comp *));
709 *nxtbuf++ = malloc( SBUFSIZ );
712 scnmsg = m_name (outnum);
713 if (*scnmsg == '?') /* msg num out of range */
717 if ((cp = unixline ()) && *cp) {
728 dmt = *dlocaltime ((long *) &st.st_mtime);
729 *datecomp->c_tws = dmt;
732 bodycomp->c_text = NULLCP;
745 (void) fputs (scanl, stdout);