SRI-NOSC/mh/scansub.c

Compare this file to the similar file:
Show the results in this format:

#include "mh.h"
#include "iobuf.h"

#define FROM    13              /* Start of From field          */
#define SFROM   16              /* Length of "        "         */
#define DATE     5              /* Start of Date field          */
#define SDATE    7              /* Length                       */
#define SUBJ    31              /* Start of Subject field       */
#define SSUBJ   (79-SUBJ)       /* Size of Subject field        */
#define BSUBJ   20              /* Room needed in Sub field to  */
				/* add stuff from the body      */
#define MSGN     0              /* Start of msg name field      */
#define SMSGN    3              /* Length                       */
#define FLGS     3              /* Start of flags field         */
#define SFLGS    2              /* Width of flag field          */

struct  iobuf scnout, fout;
int errno;
char scanl[82];

scan(inb, innum, outnum, curflg)
struct iobuf *inb;
int outnum;
{

	char buf[512], name[NAMESZ], tobuf[32], frombuf[32];
	register char *cp;
	int state, subsz, first, compnum;
	static char *myname;

	if(!myname)
		myname = getlogn(getruid());
	tobuf[0] = frombuf[0] = 0;
	errno = first = 0;
	state = FLD;
	compnum = 1;

	for(;;) {

		state = m_getfld(state, name, buf, sizeof buf, inb);
		if(!first++ && state >= FLD && state != FILEEOF) {
		    if(outnum) {
			if(fcreat((cp = m_name(outnum)),&scnout)<0) {
				printf("Error creating msg "); flush();
				perror(cp); exit(-1);
			}
			chmod(cp, m_gmprot());
		    }
		    sfill(scanl, sizeof scanl);
		    scanl[sizeof scanl - 1] = 0;
		    subsz = 0;
		    tobuf[0] = 0;
		}

		switch(state) {

		case FLD:
		case FLDEOF:
		case FLDPLUS:
			compnum++;
			if(uleq(name, "from"))
				frombuf[cpyfrm(buf, frombuf, sizeof frombuf)]=0;
			else if(uleq(name, "date"))
				cpydat(buf, scanl+DATE, SDATE);
			else if(uleq(name, "subject") && scanl[SUBJ] == ' ')
				subsz = cpy(buf, scanl+SUBJ, SSUBJ);
			else if(uleq(name, "to") && !tobuf[0])
				tobuf[cpyfrm(buf, tobuf, sizeof tobuf-1)] = 0;
			else if(uleq(name, "replied"))
				cpy("-", scanl+FLGS+1, 1);
			put(name, buf, &scnout);
			while(state == FLDPLUS) {
				state=m_getfld(state,name,buf,sizeof buf,inb);
				puts(buf, &scnout);
			}
			if(state == FLDEOF)
				goto putscan;
			continue;

		case BODY:
		case BODYEOF:
			compnum = -1;
			if(buf[0] && subsz < SSUBJ - BSUBJ) {
				scanl[SUBJ+subsz+1] = '<';
				scanl[SUBJ+subsz+2] = '<';
				cpy(buf, scanl+SUBJ+subsz+3, SSUBJ-subsz-3);
				subsz = SSUBJ;
			}
			if(buf[0] && scnout.b_fildes) {
				putc('\n', &scnout);
				if(errno) {
					perror("Write error:");exit(-1);
				}
			}
			puts(buf, &scnout);
			while(state == BODY) {
				state=m_getfld(state,name,buf,sizeof buf,inb);
				puts(buf, &scnout);
			}
			if(state == BODYEOF) {
		  putscan:      cpymsgn(m_name(innum), scanl+MSGN, SMSGN);
				if(!frombuf[0] || uleq(frombuf, myname)) {
					cpy("To:", scanl+FROM, 3);
					cpy(tobuf, scanl+FROM+3, SFROM-3);
				} else
					cpy(frombuf, scanl+FROM, SFROM);
				if(curflg)
					cpy("+", scanl+FLGS, SFLGS);
				trim(scanl);
				puts(scanl, &fout);

				if(scnout.b_fildes) {
					fflush(&scnout);
					if(errno) {
						perror("Write error");
						exit(-1);
					}
					close(scnout.b_fildes);
					scnout.b_fildes = 0;
				}
				return(1);
			}
			break;

		case LENERR:
		case FMTERR:
			printf("??Message Format Error ");
			if(outnum) printf("(Message %d) ", outnum);
			if(compnum < 0) printf("in the Body.\n");
			else printf("in Component #%d.\n", compnum);
			goto badret;
		default:
			printf("Getfld returned %d\n", state);
	badret:         if(scnout.b_fildes)
				fflush(&scnout);
			return(-1);
		case FILEEOF:
			return(0);

		}

	}
}


trim(str)
{
	register char *cp;

	cp = str;
	while(*cp) cp++;
	while(*--cp == ' ') ;
	cp++;
	*cp++ = '\n';
	*cp++ = 0;
}

sfill(str, cnt)
{
	register char *cp;
	register int i;

	cp = str;  i = cnt;
	do
		*cp++ = ' ';
	while(--i);
}


put(name, buf, iob)
{
	register struct iobuf *ip;

	ip = iob;
	if(ip->b_fildes) {
		puts(name, iob);
		putc(':', iob);
		if(errno) { perror("Write error");exit(-1);}
		puts(buf, iob);
	}
}


cpy(sfrom, sto, cnt)
{
	register char *from, *to;
	register int c;
	int i;

	from = sfrom;  to = sto;
	i = cnt;
	while(*from == ' ' || *from == '\t' || *from == '\n')
		from++;
	while(i--)
		if(c = *from) {
			if(c == '\t' || c == ' ' || c == '\n') {
				*to++ = ' ';
				do 
					from++;
				while((c= *from)==' '||c=='\t'||c=='\n');
				continue;
			} else
				*to++ = c;
			from++;
		} else
			break;
	return(from - sfrom - 1);
}


cpydat(sfrom, sto, cnt)
{
	register char *from, *cp;
	register int c;
	static int *locvec;
	long now;
	char *to;

	if(!locvec) {
		time(&now);
		locvec = localtime(&now);
	}
	to = sto;
	for(from = sfrom; (c = *from) < '0' || c > '9'; from++)
		if(!c)
			return;
	c = cnt;
	for(cp = from; (*cp >= '0' && *cp <= '9') || *cp == ' '; cp++);
	if(cp = findmonth(cp)) {
		if(!cp[1]) {
			*to++ = ' ';
			c--;
		}
		while(*cp && c--)
			*to++ = *cp++;
		c--;  *to++ = '/';
		if(from[1] == ' ') {
			*to++ = ' ';
			c--;
		}
		while(*from >= '0' && *from <= '9' && c--)
			*to++ = *from++;
		if(c >= 2) {
			while(*from < '0' || *from > '9') from++;
			if((c = atoi(from)) > 1970 && c-1900 < locvec[5]) {
				*to++ = '/';
				*to++ = c - 1970 + '0';
			}
		}
		return;
	}
	if(from[1] == ' ') {
		*to++ = ' ';
		c--;
	}
	while(*from && c--)
		*to++ = *from++;
}


char    *fromp, fromdlm, pfromdlm;

cpyfrm(sfrom, sto, cnt)
{
	register char *to, *cp;
	register int c;

	fromdlm = ' ';
	fromp = sfrom; to = sto;
	cp = frmtok();
	do
		if(c = *cp++)
			*to++ = c;
		else
			break;
	while(--cnt);
	for(;;) {
		if(cnt < 3) break;
		if(*(cp = frmtok()) == 0) break;
		if(*cp == '@' || uleq(cp, "at")) {
			cp = frmtok();
			if(!uleq(cp, "rand-unix")) {
				*to++ = '@';
				cnt--;
				do
					if(c = *cp++)
						*to++ = c;
					else
						break;
				while(--cnt);
			}
		} else if(cnt > 4) {
			cnt--; *to++ = pfromdlm;
			do
				if(c = *cp++)
					*to++ = c;
				else
					break;
			while(--cnt);
		}
	}
	return(to - sto);
}


frmtok()
{
	static tokbuf[64];
	register char *cp;
	register int c;

	pfromdlm = fromdlm;
	cp = tokbuf; *cp = 0;
	while(c = *fromp++) {
		if(c == '\t')
			c = ' ';
		if(c == ' ' && cp == tokbuf)
			continue;
		if(c == ' ' || c == '\n' || c == ',')
			break;
		*cp++ = c;
		*cp = 0;
		if(c == '@' || *fromp == '@' || cp == &tokbuf[63])
			break;
	}
	fromdlm = c;
	return(tokbuf);
}


/*      num specific!         */

cpymsgn(msgnam, addr, len)
char *msgnam, *addr;
{
	register char *cp, *sp;

	sp = msgnam;
	cp = addr + (len - length(sp));
	while(*sp)
		*cp++ = *sp++;
}

char *monthtab[] {
	"jan", "feb", "mar", "apr", "may", "jun",
	"jul", "aug", "sep", "oct", "nov", "dec",
};

findmonth(str)
{
	register char *cp, *sp;
	register int i;
	char buf[4];

	for(cp=str, sp=buf; (*sp++ = *cp++) && sp < &buf[3] && *cp != ' '; );
	*sp = 0;
	for(i = 0; i < 12; i++)
		if(uleq(buf, monthtab[i]))
			return(locv(0, i+1));
	return(0);
}