/* 
 * rmail/lmail patch v2.0
 * see copyright.doc for copyright information
 *
 * ** READ THIS -- IMPORTANT **
 * 
 * FOR SYSTEMS WITHOUT SENDMAIL:
 * To install this patch, you MUST rename your system's /bin/rmail as  
 * /bin/rmail.real and then compile this program into /bin/rmail.  When
 * rmail is called by UUCP, this program executes first, checking to see if
 * the recipient is a Citadel user.  If it is, the Citadel networker is called
 * to process the message.  If not, or if the recipient is not on this machine,
 * rmail.real is called to process the message in the conventional way.
 *
 * FOR SYSTEMS WITH SENDMAIL:
 * Most sendmail implementations use a seperate program "/bin/lmail" to deliver
 * mail to local users.  If yours has this, rename this program to lmail.c,
 * then move your system's /bin/lmail to /bin/lmail.real and compile this
 * program into /bin/lmail (same as the non-sendmail instructions above,
 * except that you are patching lmail instead of rmail).  This should allow
 * Citadel users to receive mail through all channels (UUCP, SMTP, etc.)
 *
 */

#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include "citadel.h"
#define LOCAL 0
#define REMOTE 1

#undef tolower
#define tolower(x) isupper(x) ? (x+'a'-'A') : x
char *malloc();
long lseek();
long atol();
char nodename[16];

#ifdef NEW_CONFIG
	struct config config;
#endif

#ifdef strucmp
#undef strucmp
#endif
strucmp(st1,st2)
char st1[],st2[]; {
	char *ss1,*ss2;
	int a;
	ss1=malloc(strlen(st1)+1);
	ss2=malloc(strlen(st2)+1);
	for (a=0; a<strlen(st1); ++a) *(ss1+a)=tolower(st1[a]);
	for (a=0; a<strlen(st2); ++a) *(ss2+a)=tolower(st2[a]);
	a=strcmp(ss1,ss2);
	free(ss1); free(ss2);
	return(a);
	}

struncmp(st1,st2,l)
char st1[],st2[];
int l; {
	char *ss1,*ss2;
	int a;
	ss1=malloc(strlen(st1)+1);
	ss2=malloc(strlen(st2)+1);
	for (a=0; a<strlen(st1); ++a) *(ss1+a)=tolower(st1[a]);
	for (a=0; a<strlen(st2); ++a) *(ss2+a)=tolower(st2[a]);
	a=strncmp(ss1,ss2,l);
	free(ss1); free(ss2);
	return(a);
	}

haschar(st,ch)
char st[];
int ch; {
	int a,b;
	b=0;
	for (a=0; a<strlen(st); ++a) if (st[a]==ch) ++b;
	return(b);
	}

int iscitmail(recp)
char recp[]; {
	struct usersupp ust;
	long lookfor;
	char a_recp[128];
	int a,us;

	if (!struncmp(recp,"room_",5)) {
		strcpy(recp,&recp[5]);
		for (a=0; a<strlen(recp); ++a) if (recp[a]=='_') recp[a]=32;
		return(1);
		}

	strcpy(a_recp,recp);
	for (a=0; a<strlen(a_recp); ++a)
		if (a_recp[a]=='_') a_recp[a]=32;

	lookfor = (-1L); if (!struncmp(recp,"cit",3)) lookfor=atol(&recp[3]);
	us=open("/gm/ucit/usersupp",O_RDONLY);
	if (us>=0) {
		while(read(us,&ust,sizeof(struct usersupp))>0) {
			if (lookfor == ust.eternal) {
				strcpy(recp,ust.fullname);
				close(us);
				return(2);
				}
			if (!struncmp(ust.fullname,a_recp,strlen(a_recp))) {
				strcpy(recp,ust.fullname);
				close(us);
				return(3);
				}
			}
		close(us);
		}
	return(0);
	}

main(argc,argv)
int argc;
char *argv[]; {
	static char from[1024];
	static char recp[1024];
	static char buf[1024];
	char noncitmailer[64];
	int mtype,a,b,eflag;
	long pos;

	if (argc!=2) exit(1);
	sprintf(noncitmailer,"%s.real",argv[0]);
	strcpy(recp,argv[1]);

	if (	(haschar(recp,'!'))
	     || (haschar(recp,'@'))
	     || (haschar(recp,'%'))) execlp(noncitmailer,argv[0],argv[1],NULL);

#ifdef NEW_CONFIG
	get_config();		/* for Cit/UX 3.2 and above with config file */
#else
	chdir(BBSDIR);		/* for old Cit/UX with sysconfig.h defs only */
#endif

	mtype=iscitmail(recp);
	if (mtype==0) execlp(noncitmailer,argv[0],argv[1],NULL);

	eflag=0;
	fgets(from,1024,stdin);
	from[strlen(from)-1]=0;
	if (strncmp(from,"From ",5)) exit(2);
	strcpy(from,&from[5]);
	for (a=0; a<strlen(from); ++a)
		if (!strncmp(&from[a],"remote from ",12)) {
			strcpy(buf,&from[a+12]);
			from[a-1]=0;
			strcat(buf,"!"); strcat(buf,from);
			strcpy(from,buf);
			}

	if (mtype==1) do_roommail(from,recp);
	if (mtype>=2) do_citmail(from,recp);

	exit(0);
	}

do_citmail(from,recp)  /* pipe message through netproc */
char from[];
char recp[]; {
	long now;
	FILE *temp;
	int a;
	static char buf[128];
	static char frombuf[128];
	static char nodebuf[128];

	time(&now);
	for (a=0; a<strlen(from); ++a) if (from[a]==32) from[a]=0;
	temp=popen("./rnews -c","w");
	putc(255,temp); putc(MES_NORMAL,temp); putc(1,temp);
	strcpy(frombuf,"UUCP Mailer");
	strcpy(nodebuf,nodename);
	while ( (fgets(buf,128,stdin)!=NULL) && (buf[1]!=0) ) {
		buf[strlen(buf)-1]=0;
		if (!strncmp(buf,"From: ",6)) {
			strcpy(frombuf,&buf[6]);
			for (a=0; a<strlen(frombuf); ++a) {
				if (frombuf[a]=='<') frombuf[a-1]=0;
				if (frombuf[a]==')') frombuf[a]=0;
				if (frombuf[a]=='(') {
					strcpy(frombuf,&frombuf[a+1]);
					a=0;
					}
				}
			strcpy(nodebuf,&buf[6]);
			for (a=0; a<strlen(nodebuf); ++a) {
				if ((nodebuf[a]=='<')||(nodebuf[a]=='@')) {
					strcpy(nodebuf,&nodebuf[a+1]);
					a=0;
					}
				if (nodebuf[a]=='>') nodebuf[a]=0;
				if (nodebuf[a]=='(') nodebuf[a-1]=0;
				}
			}
		}
	fprintf(temp,"P%s",from); putc(0,temp);
	fprintf(temp,"T%ld",now); putc(0,temp);
	fprintf(temp,"A%s",frombuf); putc(0,temp);
	fprintf(temp,"OMail"); putc(0,temp);
	fprintf(temp,"N%s",nodebuf); putc(0,temp);
	fprintf(temp,"R%s",recp); putc(0,temp);
	putc('M',temp);
	fprintf(temp,"Path: %s\n",from);
	while (a=getc(stdin), a>0) putc(a,temp);
	putc(0,temp);
	pclose(temp);
	return(0);
	}

do_roommail(from,recp)  /* pipe public message through netproc */
char from[];
char recp[]; {
	long now;
	FILE *temp;
	int a;
	static char buf[128];
	static char frombuf[128];
	static char nodebuf[128];

	time(&now);
	for (a=0; a<strlen(from); ++a) if (from[a]==32) from[a]=0;
	temp=popen("./rnews -c","w");
	putc(255,temp); putc(MES_NORMAL,temp); putc(1,temp);
	strcpy(frombuf,"UUCP Mailer");
	strcpy(nodebuf,nodename);
	while ( (fgets(buf,128,stdin)!=NULL) && (buf[1]!=0) ) {
		buf[strlen(buf)-1]=0;
		if (!strncmp(buf,"From: ",6)) {
			strcpy(frombuf,&buf[6]);
			for (a=0; a<strlen(frombuf); ++a) {
				if (frombuf[a]=='<') frombuf[a-1]=0;
				if (frombuf[a]==')') frombuf[a]=0;
				if (frombuf[a]=='(') {
					strcpy(frombuf,&frombuf[a+1]);
					a=0;
					}
				}
			strcpy(nodebuf,&buf[6]);
			for (a=0; a<strlen(nodebuf); ++a) {
				if ((nodebuf[a]=='<')||(nodebuf[a]=='@')) {
					strcpy(nodebuf,&nodebuf[a+1]);
					a=0;
					}
				if (nodebuf[a]=='>') nodebuf[a]=0;
				if (nodebuf[a]=='(') nodebuf[a-1]=0;
				}
			}
		}
	fprintf(temp,"P%s",from); putc(0,temp);
	fprintf(temp,"T%ld",now); putc(0,temp);
	fprintf(temp,"A%s",frombuf); putc(0,temp);
	fprintf(temp,"O%s",recp); putc(0,temp);
	fprintf(temp,"N%s",nodebuf); putc(0,temp);
	putc('M',temp);
	while (a=getc(stdin), a>0) putc(a,temp);
	putc(0,temp);
	pclose(temp);
	return(0);
	}
