⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scansbr.c

📁 早期freebsd实现
💻 C
字号:
/* scansbr.c - routines to help scan along... */#ifndef	lintstatic char ident[] = "@(#)$Id: scansbr.c,v 1.15 1993/08/20 15:54:08 jromine Exp $";#endif	/* lint */#include "../h/mh.h"#include "../h/addrsbr.h"#include "../h/formatsbr.h"#include "../h/scansbr.h"#include "../zotnet/tws.h"#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#ifdef _FSTDIO#define       _ptr    _p              /* Gag */#define       _cnt    _w              /* Wretch */#endif#define MAXSCANL 256		/* longest possible scan line */#define SBUFSIZ 512		/* buffer size for content part of header				 * fields.  We want this to be large				 * enough so that we don't do a lot of				 * extra FLDPLUS calls on m_getfld but				 * small enough so that we don't snarf				 * the entire message body when we're				 * only going to display 30 characters				 * of it.				 *//*  */static struct format *fmt;#ifdef JLRstatic struct format *fmt_top;#endif /* JLR */static struct comp *datecomp;		/* pntr to "date" comp */static struct comp *bodycomp;		/* pntr to "body" pseudo-comp 					 * (if referenced) */static int	ncomps = 0;		/* # of interesting components */static char	**compbuffers = 0; 	/* buffers for component text */static struct comp **used_buf = 0;	/* stack for comp that use buffers */char    	*scanl = 0;		/* text of most recent scanline */static int  dat[5];			/* aux. data for format routine */#ifdef	RPATHSchar   *unixline ();			/* info from UNIX From: line */#endif	/* RPATHS */#define FPUTS(buf) {\		if (mh_fputs(buf,scnout) == EOF)\		    adios (scnmsg, "write error on");\		}/*  *//* ARGSUSED */int     scan (inb, innum, outnum, nfs, width, curflg,					unseen, folder, size, noisy)char	*nfs,	*folder;int     innum,        outnum,	width,        curflg,	unseen,	noisy;long	size;register FILE   *inb;{    int     compnum,	    encrypted,            state;    register int  i;    register char *cp;    register struct comp *cptr;    register char *tmpbuf;    register char **nxtbuf;    register struct comp **savecomp;    char    *scnmsg;    FILE    *scnout;    char    name[NAMESZ];    static  int rlwidth,	        slwidth;    /* first-time only initialization */    if (scanl == NULLCP) {	int	bigwid;	if (width == 0) {	    if ((width = sc_width ()) < WIDTH/2)		width = WIDTH/2;	    else if (width > MAXSCANL)		width = MAXSCANL;	}	dat[3] = slwidth = width;	if ((scanl = (char *)malloc( (unsigned) (slwidth + 2) )) == (char *)0)	    adios (NULLCP, "unable to malloc scan line (%d bytes)", slwidth+2);	if (outnum)	    (void) umask( ~ m_gmprot() );	ncomps = fmt_compile (nfs, &fmt) + 1;#ifdef JLR	fmt_top = fmt;#endif	/* JLR */	FINDCOMP(bodycomp, "body");	FINDCOMP(datecomp, "date");	FINDCOMP(cptr, "folder");	if (cptr && folder)	    cptr->c_text = folder;	FINDCOMP(cptr, "encrypted");	if (!cptr)	    if (cptr = (struct comp *) calloc (1, sizeof *cptr)) {		cptr -> c_name = "encrypted";		cptr -> c_next = wantcomp[i = CHASH (cptr -> c_name)];		wantcomp[i] = cptr;		ncomps++;	}	FINDCOMP (cptr, "dtimenow");	if (cptr)	    cptr->c_text = getcpy(dtimenow ());	nxtbuf = compbuffers = (char **)calloc((unsigned) ncomps,	    sizeof(char *));	if (nxtbuf == NULL)	    adios (NULLCP, "unable to allocate component buffers");	used_buf = (struct comp **)calloc((unsigned) (ncomps+1),	    sizeof(struct comp *));	if (used_buf == NULL)	    adios (NULLCP, "unable to allocate component buffer stack");	used_buf += ncomps+1; *--used_buf = 0;	rlwidth = bodycomp && (width > SBUFSIZ) ? width : SBUFSIZ;	for (i = ncomps; i--; )	    if ((*nxtbuf++ = malloc( rlwidth )) == NULL)		adios (NULLCP, "unable to allocate component buffer");    }    /* each-message initialization */    nxtbuf = compbuffers;    savecomp = used_buf;    tmpbuf = *nxtbuf++;    dat[0] = innum ? innum : outnum;    dat[1] = curflg;    dat[4] = unseen;    /*     * get the first field.  If the msg is non-empty and we're doing     * an "inc", open the output file.     */    if ((state = m_getfld (FLD, name, tmpbuf, rlwidth, inb)) == FILEEOF)	if (ferror(inb)) {	    advise("read", "unable to"); /* "read error" */	    return SCNFAT;	} else	    return SCNEOF;    if (outnum) {	if (outnum > 0) {	/* Fix from Van -- I'm not sure why... */	    scnmsg = m_name (outnum);	    if (*scnmsg == '?')	/* msg num out of range */		return SCNNUM;	}	else	    scnmsg = "/dev/null";	if ((scnout = fopen (scnmsg, "w")) == NULL)	    adios (scnmsg, "unable to write");#ifdef	RPATHS	if ((cp = unixline ()) && *cp != '\n') {	    FPUTS ("Return-Path: ");	    FPUTS (cp);	}#endif	/* RPATHS */    }    /* scan - main loop */    for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, rlwidth, inb)) {	switch (state) {	    case FLD: 	    case FLDPLUS: 		compnum++;		if (outnum) {		    FPUTS (name);		    (void) putc (':', scnout);		    FPUTS (tmpbuf);		}		/*		 * if we're interested in this component, save a pointer		 * to the component text, then start using our next free		 * buffer as the component temp buffer (buffer switching		 * saves an extra copy of the component text).		 */		if (cptr = wantcomp[CHASH(name)])		    do {			if (uleq(name, cptr->c_name)) {			    if (! cptr->c_text) {				cptr->c_text = tmpbuf;				for (cp = tmpbuf + strlen (tmpbuf) - 1; 					cp >= tmpbuf; cp--)				    if (isspace (*cp))					*cp = 0;				    else					break;				*--savecomp = cptr;				tmpbuf = *nxtbuf++;			    }			    break;			}		    } while (cptr = cptr->c_next);		while (state == FLDPLUS) {		    state = m_getfld (state, name, tmpbuf, rlwidth, inb);		    if (outnum)			FPUTS (tmpbuf);		}		break;	    case BODY: 		compnum = -1;		if (! outnum) {		    state = FILEEOF; /* stop now if scan cmd */		    goto finished;		}		(void) putc ('\n', scnout);		FPUTS (tmpbuf);		/*		 * performance hack: some people like to run "inc" on		 * things like net.sources or large digests.  We do a		 * copy directly into the output buffer rather than		 * going through an intermediate buffer.		 *		 * We need the amount of data m_getfld found & don't		 * want to do a strlen on the long buffer so there's		 * a hack in m_getfld to save the amount of data it		 * returned in the global "msg_count".		 */	body: 	;		while (state == BODY) {		    if (scnout->_cnt <= 0) {			if (fflush(scnout) == EOF)			    adios (scnmsg, "write error on");		    }		    state = m_getfld( state, name, scnout->_ptr,				      -(scnout->_cnt), inb );		    scnout->_cnt -= msg_count;		    scnout->_ptr += msg_count;		}		goto finished;	    case LENERR: 	    case FMTERR: 		fprintf (stderr, 			innum ? "??Format error (message %d) in "			      : "??Format error in ",			outnum ? outnum : innum);		fprintf (stderr, "component %d\n", compnum);		if (outnum) {		    FPUTS ("\n\nBAD MSG:\n");		    FPUTS (name);		    (void) putc ('\n', scnout);		    state = BODY;		    goto body;		}		/* fall through */	    case FILEEOF:		goto finished;	    default: 		adios (NULLCP, "getfld() returned %d", state);	}    }    /*     * format and output the scan line.     */finished:    if (ferror(inb)) {	advise("read", "unable to"); /* "read error" */	return SCNFAT;    }    {	char *saved_c_text;	if (bodycomp) {	    /* Save and restore buffer so we don't trash our dynamic pool! */	    saved_c_text = bodycomp->c_text;	    bodycomp->c_text = tmpbuf;	}	if (size)	    dat[2] = size;	else if (outnum > 0)	    dat[2] = ftell(scnout);	if ( (datecomp && ! datecomp->c_text) || (!size && !outnum)) {	    struct stat st;	    (void) fstat (fileno(inb), &st);	    if (!size && !outnum)		dat[2] = st.st_size;	    if (datecomp) {		if (! datecomp->c_text) {		    if (datecomp->c_tws == NULL)			datecomp->c_tws = (struct tws *)			    calloc((unsigned) 1, sizeof(*datecomp->c_tws));		    if (datecomp->c_tws == NULL)			adios (NULLCP, "unable to allocate tws buffer");  		    *datecomp->c_tws = *dlocaltime ((long *) &st.st_mtime);		    datecomp->c_flags = -1;		} else {		    datecomp->c_flags = 0;		}	    }	}#ifndef JLR	(void) fmtscan (fmt, scanl, slwidth, dat);#else	/* JLR */	fmt = fmtscan (fmt, scanl, slwidth, dat);	if (!fmt)	    fmt = fmt_top;		/* reset for old format files */#endif	/* JLR */	if (bodycomp)	    bodycomp->c_text = saved_c_text;    }    if (noisy)	(void) fputs (scanl, stdout);    FINDCOMP (cptr, "encrypted");    encrypted = cptr && cptr -> c_text;    /* return dynamically allocated buffers to pool */    while ( cptr = *savecomp++ ) {	*--nxtbuf = cptr->c_text;	cptr->c_text = NULLCP;    }    *--nxtbuf = tmpbuf;    if (outnum && fclose (scnout) == EOF)	adios (scnmsg, "write error on");    return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);}/*  *//* Cheat:  we are loaded with adrparse, which wants a routine called   OfficialName().  We call adrparse:getm() with the correct arguments   to prevent OfficialName() from being called.  Hence, the following   is to keep the loader happy. */char   *OfficialName (name)register char  *name;{    return name;}mh_fputs(s, stream)char *s;FILE *stream;{    char    c;    while(c = *s++) 	if(putc(c,stream) == EOF )	    return(EOF);    return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -