SRI-NOSC/s1/ex.source

#/*
Module Name:
	ex.source

Installation:
	ln ex.source ex.c
	if $1x = finalx goto final
	cc ex.c -lj
	rm -f ex.c
	exit
: final
	cc -O -s ex.c -lj
	if ! -r a.out exit
	su cp a.out /usr/bin/ex
	rm -f a.out ex.c

Synopsis:
	ex [ -f filename ] [ - ] [ -s subject ] [ -o ]

Function:
	Extract the body of a message and write it as a file with the same
	name as the subject line.

	Parameters:
		-f  use the specified filename as input

		-   equivalent to -f <std input>

		-s  extract only the specified subject

		-o  put output on std output

Compile time parameters and effects:
	MBX	the name of the default mailbox to be scanned

	MSGSEP	the separator inserted by the recieving mailer

Module History:
	Written 14 Dec 77 by Greg Noel
	Mods by R Balocca 78Jan6 :
		added all the options
		added includes
		general massaging for CAC system
	Modified 23Jan78 by Greg Noel
		removed includes to permit easier transportability
		added defines
		tinkered with logic slightly to improve speed
*/

#define MBX ".mail"	/* default mailbox name */
#define MSGSEP "\1\1\1\1" /* end-of-message inserted by recieving mailer */

char line[500];

int fi;		/* output file designator */

struct {	/* input file buffering */
	int fid;	/* file descriptor */
	int nleft;	/* chars left in buffer */
	char *nextp;	/* ptr to next character */
	char buff[512];	/* the buffer */
} in;

main(argc, argv)
int argc;
char **argv;
{
	register int len;
	register char *p;
	register char * fname;
	static char * subj;	/* static for the 0 */
	static int output;	/* ditto */

	/* set up */

	for(fname = MBX,in.fid = -1;;)
	{
		argc--; argv++;
		if(argc<=0)
			break;
		if(argv[0][0] == '-')
		{
			switch(argv[0][1])
			{
			case 'f':		/* particular input file */
				fname = argv[1];
				argc--; argv++;
				break;
			case '\0':
				in.fid = 0;
				break;
			case 's':		/* particular subject line */
				subj = argv[1];
				argc--; argv++;
				break;
			case 'o':		/* output on stdout */

				output = 1;
				break;
			}
		}
	}
	if(in.fid == -1 && fopen(fname, &in) < 0) {
		printf(2, "Bad input file specification\n");
		flush();
		exit();
	}

	/* go through file extracting texts */

for(;;){
	for(;;)
	{
		len = getline();
		line[8] = 0;
		if(strcomp(line, "Subject:") == 0)
		{
			if(subj == 0)
				break;
			else
			{
				line[len-1] = '\0';	/* sorry */
				if(strcomp(subj, &line[9]) == 0)
					break;
				line[len-1] = '\n';
			}
		}
	}
	/* should strip off leading blanks on &line[9] */

	/* found subject line; get filename */

	line[len-1] = 0;	/* change newline to null */
	if( output )
		fi = dup(1);
	else
	if( (fi = creat(&line[9], 0644)) < 0) {
		printf(2, "Can't open file: '%s'\n", &line[9]);
		flush();
		/* should make up name... */
		fi = dup(1);	/* so put it on std output */
	}

	/* skip past rest of header */

	while(getline() > 1);

	/* copy body to output file */

	for(;;) {
		if((len = getline()) > 5) {
			for(p = line; *p++ == '-';);
			if(*--p == '\n')
				break;	/* trailing hyphens put on by mailer */
		}
		line[len-1] = '\0';			/* sorry */
		if(strcomp(line, MSGSEP) == 0) break;
			/* mail marker inserted by recieving mailer */
		line[len-1] = '\n';
		write(fi, line, len);
	}

	/* close up shop on this file */

	close(fi);
	flush();
}
}
getline()
{
	register char *p;

	p = line;
	do {
		if( (*p = getc(&in)) < 0) exit();
	} while(*p++ != '\n');
	*p = 0;	/* null terminate */
	return(p-line);
}
strcomp(a, b)
char *a, *b;
{
	register char *p, *q, c;

	p = a;  q = b;
	while( (c = *p++) == *q++  &&  c);
	return(*--p - *--q);
}