/* prt2mail translator for use with Charon
	Copyright (C) 1990 Brad K. Clements, Clarkson University
	       All Rights Reserved.
	
	converts incoming printouts into mail messages.

	Incoming print jobs must be formatted as follows:

	       Max width, 80 chars

	       <Header Line>
		From Address	< the text name, the userid is taken from charon >
		Recipients   <one per line>
		<blank line>
		Subject:	Subject text
		The body of the message.

		The Header line is as follows
		       	$$mailformat1

*/

#include <ctype.h> 
#include <time.h>
#include <string.h>
#ifndef	STANDALONE
#define	STANDALONE	0
#endif
#include "callback.h"
#include "tagvalue.h"

char	*stackinfo="$STACKSIZE:4096";
#define	BUFFSIZE	256
#define	MAXTOS		10

#if	STANDALONE
#include	<fcntl.h>
#undef	STDIN
#define	STDIN	sin
#endif
int	sin;

int
main(int argc, char *argv[])
{
	int 	rc;
	unsigned	header_flags;
	char		ibuffer[BUFFSIZE], obuffer[BUFFSIZE], *c;
	char		*inlimit, *outlimit, *outc;
	enum		mode { HEADER, FROM, TO, SUBJECT, DATA } Mode = HEADER;
	int		lastwas_cr = 0, needline = 1;
	int		inbytes;
	long		start = time(NULL);
	long		end;
	char		from[128];
	char		tos[MAXTOS][128];
	int		tocount = 0;
	int		leadingspace = 1;

#if	STANDALONE
	sin = open("sample.prt",O_RDONLY|O_BINARY);
#endif
	outlimit = obuffer + BUFFSIZE -2;
	outc = obuffer;
	while(1) {
		/* read one line at a time */
		inbytes = read(STDIN,ibuffer, BUFFSIZE);
		if(inbytes < 1)
			break;
		inlimit = ibuffer + inbytes;
		c = ibuffer;
		while(1) {
			while(needline && c < inlimit && outc < outlimit) {
			       	switch (*c) {

				       	case 13 :
					       	lastwas_cr = 1;
					 	needline = 0;
						*outc++ = 0;
					       	break;
					case 10 :
						if(!lastwas_cr)
						       	needline = 0;
						lastwas_cr = 0;
					       	break;
					default :
					       	lastwas_cr = 0;
					 	if(Mode != DATA && leadingspace) {
						       	if(isspace(*c))
							       	break;
							leadingspace = 0;
						}
						*outc++ = *c;
			        }	/* end switch *c */
				c++;
			}	/* end while c < inlimit */
			if(outc >= outlimit) {
				fprintf(STDERR,"Warn! Output buffer overflow\n");
			}
			if(!needline) {	/* have some work to do */
			       	leadingspace = 1;
			       	switch (Mode) {
				 	case HEADER :	/* first line is header */
					       	if(!strlen(obuffer))
						       	break;		/* skip leading blanks */
					       	if(strcmp(obuffer,"$$mailformat1")) {
							/* bogus */
							fprintf(STDERR,"Mailformed first line (%s)\n",obuffer);
						 	return(RT_FAILED);
						}
						Mode = FROM;
						break;
					 case	FROM :
						strcpy(from, obuffer);
					 	Mode = TO;
					 	break;
					case 	TO :
					       	if(!strlen(obuffer)) {	/* done */
							 char	tt[36];
						  	 long	now;

							 if(tocount < 1) {
								fprintf(STDERR,"No recipients found\n");
								return(RT_FAILED);
							 }
							 fprintf(STDOUT,"$$\r\n");
							 for(rc = 0; rc < tocount; rc++)
									fprintf(STDOUT,"%s\r\n",tos[rc]);
							 fprintf(STDOUT,"\r\n");
							 fprintf(STDOUT,"From:     %c%s%c <%s",34,from,34,
									getenv(TV_SourceObject));
							 fprintf(STDOUT,"@%s>\r\n", getenv(TV_SourceIHost));
						  			/* getenv is simulated with static area..
									   so you can't call it twice in a row */
							 for(rc = 0; rc < tocount; rc++) {
									if(!rc)
										fprintf(STDOUT,"To:       %s",tos[0]);
									else
										fprintf(STDOUT,"%s",tos[rc]);
									if(rc+1 < tocount)
										fprintf(STDOUT,",\r\n         ");
							 }	/* end for */
							 fprintf(STDOUT,"\r\n");
							 time(&now);
							 strcpy(tt, ctime(&now));
							 tt[3] = 0;
							 tt[7] = 0;
							 tt[0xa] = 0;
							 tt[0x13] = 0;
							 tt[0x18] = 0;
							 fprintf(STDOUT,"Date:     %s %s %s %s\r\n",&tt[8],&tt[4],&tt[0x16],&tt[0xb]);
							 Mode = SUBJECT;
							 sprintf(obuffer,"%s=%s",TV_NextJobTypes, TVJT_MAILER);
							 setenv(obuffer);
							 break;
					        }
					 	if(tocount < MAXTOS) {
						       	strcpy(&tos[tocount++][0],obuffer);
						}
					 	else {
						       	fprintf(STDERR,"Max recipients exceeded, discarding: %s\n",obuffer);
						}
					 	break;
					case	SUBJECT :
					       	Mode = DATA;
					 	fprintf(STDOUT,"%s\r\n\r\n",obuffer);
						break;
					case	DATA :
					       	fprintf(STDOUT,"%s\r\n",obuffer);
				} /* end switch mode */
				needline = 1;
			 	outc = obuffer;
		        }	/* end if !needline */
		 	if(c >= inlimit) {
				break;
			}
	        }	/* end while 1 (break into lines loop) */
       }	/* end while 1 (main input loop) */
	if(Mode == DATA && outc > obuffer) {
	       	*outc++ = 0;
	 	fprintf(STDOUT,"%s\r\n",obuffer);
	}
	time(&end);
	fprintf(STDERR,"Translated %ld input bytes, %ld output bytes in %d seconds\n",tellp(STDIN), tellp(STDOUT), (int) end-start);
	return(RT_OK|RT_CHANGED_TEXT|RT_CHANGED_TAGS);
}

