#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <direct.h>

#define FALSE 0
#define TRUE (!FALSE)

int article_read(void);
int article_munge(void);
int article_save(void);
int article_send(void);
void emsg(char * arg_list, ...);
int dolog(char *s);

#define BFSZ 600
static char tosite[BFSZ];
static char spool[BFSZ];
static char togroup[BFSZ];
static char infile[BFSZ];
static char approved[BFSZ];
static char admin[BFSZ];
static char fromlist[BFSZ];
static char xto[BFSZ];
static char xsubject[BFSZ];
static char xfrom[BFSZ];
static char logname[BFSZ];

int main(int argc, char *argv[])
{
	char bf[300];
	static char bf2[300];
	int article_ok;
	char *s;
	int i;

	if (argc<2) {
	 	printf("Usage: drobot -dir c:\\ntmail\\news -group comp.os.vms -admin you@this.site -from list@here \n");
		goto ret;
	}

	for (i=1; i<argc; i++) {
		if (strncmp(argv[i],"-dir",2)==0) {strcpy(spool,argv[++i]);}
		else if (strncmp(argv[i],"-ap",2)==0) {strcpy(approved,argv[++i]);}
		else if (strcmp(argv[i],"-to")==0) {strcpy(tosite,argv[++i]);}
		else if (strncmp(argv[i],"-g",2)==0) {strcpy(togroup,argv[++i]);}
		else if (strncmp(argv[i],"-admin",3)==0) {strcpy(admin,argv[++i]);}
		else if (strncmp(argv[i],"-from",3)==0) {strcpy(fromlist,argv[++i]);}
	}


	/* Open the input file if it isn't stdin*/
	strcpy(bf,togroup);
	for (s=bf;*s!=0; s++) {
		if (*s=='.') *s = '_';
		if (*s=='+') *s = '_';
		if (*s=='-') *s = '_';
	}
	sprintf(logname,"%s/%s.log",spool,bf);
	if (strlen(spool)==0) {emsg("Usage wrong, must give -spool d:/xxx \n"); return 0;}
	s = getenv("FROM"); if (s!=NULL) strcpy(xfrom,s);
	s = getenv("TO"); if (s!=NULL) strcpy(xto,s);
	s = getenv("SUBJECT"); if (s!=NULL) strcpy(xsubject,s);
	_mkdir(spool);
	emsg("Processing from {%s} to {%s} subject {%s}\n",xfrom,xto,xsubject); 
	if (strlen(fromlist)==0) {strcpy(fromlist,xfrom);}

 	article_ok = article_read();
	emsg("Read article ok\n");
 	 
	if (!article_ok) {emsg("Couldn't read article\n"); goto ret;}
	if (!article_munge()) {article_save(); goto ret;}
	if (!article_send()) {article_save();}
	
 ret: 	
 	return 0;
}
void emsg(char * arg_list, ...)
{
 	va_list arg_ptr;
 	char *format, output[1000];

 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	dolog(output);
}
int dolog(char *s)
{
	FILE *f;
	f = fopen(logname,"a");
	if (f!=NULL) {
		fprintf(f,"%s",s);
		fclose(f);
	}
 	return TRUE;
}


static char *content;
int article_read(void)
{
	char *tmp;
	int		contentLength;
	int		x;
	char *s;

	s =  getenv("CONTENT_LENGTH");
	if (s!=NULL) contentLength = atoi( getenv("CONTENT_LENGTH"));
	else contentLength = 10000;

	// Read the mail message from STDIN into a buffer...
	content = (char *)mymalloc( contentLength+1 );
	tmp = content;
	while ((x = fgetc( stdin )) != EOF) {
		*tmp++ = x;
		if ((tmp-content)>=contentLength) break;
	}
	*tmp = '\0';
	return TRUE;
}		


#define matches(a,b) (strncmp(a,b,strlen(b))==0)
#define EOL "\015\012"
#define addline(xx) {strcat(xout,xx); strcat(xout,EOL); xout += strlen(xx)+2;}
static char subject[BFSZ];
int article_munge(void)
{
	char *s,*s2;
	char *out;
	char *xout;
	int r = TRUE;
	int donehead = FALSE;
	int done_extras = FALSE;
	int gotreply = FALSE;
	char bf[30000];

	out = mymalloc(strlen(content)+30000);
	xout = out;
	s = content;
	s2 = strchr(s,'\012');
	for (;s2!=NULL;) {
		*s2 = 0;
		strcpy(bf,s);
		s = strchr(bf,'\015'); if (s!=NULL) *s = 0;
		s = strchr(bf,'\012'); if (s!=NULL) *s = 0;
		if (strcmp(bf,".")==0) strcpy(bf,".."); /* convert single .'s */
		if (matches(bf,"Control:")) {emsg("Rejecting control message\n"); return FALSE; }
		if (matches(bf,"Newsgroups:")) if (strlen(togroup)>0) goto cont;
		if (matches(bf,"Approved:")) if (strlen(approved)>0) goto cont;
		if (matches(bf,"Subject:")) {strcpy(subject,bf+8);}
		if (matches(bf,"To:")) goto cont; /* Illegal news headers */
		if (matches(bf,"Cc:")) goto cont; /* Illegal news headers */
		if (strlen(bf)==0) if (!done_extras) {
			done_extras = TRUE;
			if (strlen(approved)>0) {
				sprintf(bf,"Approved: %s",approved);
				addline(bf);
			}
			if (strlen(togroup)>0) {
				sprintf(bf,"Newsgroups: %s",togroup); 
				addline(bf);
			}
			if (strlen(admin)!=0) {sprintf(bf,"X-Gateway-Administrator: %s",admin);  addline(bf);}
			if (strlen(fromlist)!=0) {sprintf(bf,"X-Gateway-From: %s",fromlist);  addline(bf);}
			strcpy(bf,"");
		}
		addline(bf);

cont:		s = s2 + 1;
		s2 = strchr(s,'\012');
	}
	myfree(content);
	content = out;
	return TRUE;	
}


int article_save(void)
{
	FILE *f;
	char bf[BFSZ];
	char fname[BFSZ];
	static int upto;

	sprintf(fname,"%s/upto.cnt",spool);
 	f = fopen(fname,"r");
	if (f!=NULL) {
		fgets(bf,BFSZ-10,f);
		fclose(f);
	}
	upto = atoi(bf);
	upto++;
	f = fopen(fname,"w");
	if (f!=NULL) {
		fprintf(f,"%d\n",upto);
		fclose(f);
	}
	sprintf(fname,"%s/fail_%d.dud",spool,upto);
	emsg("Saving failed article to file {%s} \n",fname);
	f = fopen(fname,"wb");
	if (f==NULL) {perror(fname); return FALSE;}
	fwrite(content,1,strlen(content),f);
	fclose(f);
	return TRUE;

}
int article_send(void)
{
	FILE *f;
	char bf[BFSZ];
	char fname[BFSZ];
	static int upto;

	sprintf(fname,"%s/upto.cnt",spool);
 	f = fopen(fname,"r");
	if (f!=NULL) {
		fgets(bf,BFSZ-10,f);
		fclose(f);
	}
	upto = atoi(bf);
next_file:
	upto++;
	f = fopen(fname,"w");
	if (f!=NULL) {
		fprintf(f,"%d\n",upto);
		fclose(f);
	}
	sprintf(fname,"%s/news_%d.itm",spool,upto);
	emsg("Saving article to file {%s} \n",fname);
	f = fopen(fname,"r");
	if (f!=NULL) {fclose(f); goto next_file;}
	f = fopen(fname,"wb");
	if (f==NULL) {emsg("Couldn't create %s\n",fname); return FALSE;}
	fwrite(content,1,strlen(content),f);
	fclose(f);
	return TRUE;

}
