#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dosextens.h>
#include <xpr/xproto.h>
#include <xpr/xpr_lib.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <time.h>
#include <stdlib.h>
#include <dos.h>

#include "/lib/iomodes.h"
#include "/lib/misc.h"

/****************************************************************************\
*	net-program for AXsh by Pasi Ojala.										 *
*	 8-Jan-92	Pasi	Some changes										 *
*	12-Jan-92	Pasi	Changed the login-procedure again					 *
*	14-Jan-92	Pasi	Transfer stats (cps) debugged						 *
*	25-Apr-92	Pasi	Changed net to use xprzmodem.library				 *
*	25-Jun-92	Pasi	%tempdir: now defines the directory for temp packets *
\****************************************************************************/

static char vers[] = "\0$VER: net 1.1 (2.12.95)\n";

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

#define memclr(a,p) memset((void*)a,0,(int)p)

struct	Library *XProtocolBase;
#define	XPRNAME	"xprzmodem.library"
struct	XPR_IO	io;
#define XPRINIT	"TN,B32,E30,OY,AN,DN,KN,SN,RN,P"	/* receiving path to be added */

BPTR __asm __saveds c_fopen(register __a0 char * , register __a1 char * );
void __asm __saveds c_fclose(register __a0 BPTR );
long __asm __saveds c_fread(register __a0 char * , register __d0 long , register __d1 long , register __a1 BPTR );
long __asm __saveds c_fwrite(register __a0 char * , register __d0 long , register __d1 long , register __a1 BPTR );
long __asm __saveds c_finfo(register __a0 char * , register __d0 long );
long __asm __saveds c_fseek(register __a0 BPTR , register __d0 long , register __d1 long );
long __asm __saveds c_sread(register __a0 char * , register __d0 long , register __d1 long );
long __asm __saveds c_swrite(register __a0 char * , register __d0 long );
void __saveds c_sflush(void);
long __saveds c_chkabort(void);
/*
long __asm __saveds c_ffirst(register __a0 char * , register __a1 char * );
long __asm __saveds c_fnext(register __d0 long , register __a0 char * , register __a1 char * );
*/
long __asm __saveds c_setserial(register __d0 long );
void __saveds c_chkmisc(void);
long __saveds c_squery(void);
long __asm __saveds c_unlink(register __a0 char * );
long __asm __saveds c_options(register __d0 long , register __a0 struct xpr_option ** );
long __asm __saveds c_gets(register __a0 char * , register __a1 char * );
void __asm __saveds c_update(register __a0 struct XPR_UPDATE * );
void init_xprio(int );

void __regargs __chkabort(void);
void __regargs __chkabort(void){}
VOID chkabort(VOID) {}	/* don't allow ctrl-c/d */

#define LEN 80

#define RX	 0x55
#define SKIP 0xaa
#define ACKN 0x99

char	Mailhome[LEN]="AXsh:usr/spool/mail/",
		Newshome[LEN]="AXsh:usr/spool/news/",
		Host[LEN]="foo.bar.fi", /* %thismachine */
		Hub[LEN]="hub.axsh.pp.fi",
		Pass[LEN]="PaSsWoRd",
		Tmpdir[LEN]="T:";
int		oldpri=0, sendidto=300, receiveidto=600;
char	expect[12]="",elapsed[12]="",name[120]="";
long	bytes=0,size=0,cps=0;
struct  DateStamp intime,outtime;
BOOL	Online=0;


FILE *fopen(),*err=0;

void hangup(int which,char *who);
void read_config(void);
int	 getline(char *line,int maxlen,int timeout);	/* timeout in ms , 1000ms = 1sec*/
char *get_time(void);
int  caller(char *);
int  receiver(char *);
int  sendid(unsigned char ID,int acktime);
int  receiveid(int time);

BPTR __saveds __asm c_fopen( register __a0 char *name,
							register __a1 char *mode)
{	BPTR file=NULL;
	register char 	dir=mode[0],mod=mode[1];

	if(dir=='a')
	{
		if(mod=='+')
			file=Open(name,MODE_READWRITE);
		else
			file=Open(name,MODE_OLDFILE);

		if(file)	Seek(file,0,OFFSET_END);
	}
	else
	if(dir=='r')
	{
		if(mod=='+')
			file=Open(name,MODE_READWRITE);
		else
			file=Open(name,MODE_OLDFILE);
	}
	else
	if(dir=='w')
	{
		file=Open(name,MODE_NEWFILE);
	}
	return(file);
}

void __saveds __asm c_fclose(register __a0 BPTR fileptr)
{
	Close(fileptr);
}

long __saveds __asm c_fread(register __a0 char *buffer,
							register __d0 long size,
							register __d1 long count,
							register __a1 BPTR fileptr)
{
	if(fileptr)		return Read(fileptr,buffer,size*count);
	else			return -1L;
}

long __saveds __asm c_fwrite(register __a0 char *buffer,
							 register __d0 long size,
							 register __d1 long count,
							 register __a1 BPTR fileptr)
{
	if(fileptr)		return Write(fileptr,buffer,size*count);
	else			return -1L;
}

long __saveds __asm c_finfo(register __a0 char *name,
							register __d0 long info)
{	long file,len=0L;

	if(info==1)
	{
		if(file=Open(name,MODE_OLDFILE))
		{
			(void)Seek(file,0L,OFFSET_END);
			len=Seek(file,0L,OFFSET_CURRENT);
			Close(file);
		}					/* vain tiedoston pituuden tutkiminen */
	}
	if(info==2)	len=1; /* binary file */
	return(len);
}

long __saveds __asm c_fseek(register __a0 BPTR fileptr,
							register __d0 long position,
							register __d1 long origin)
{
	if(!fileptr)	return -1;
	switch(origin)
	{
	case SEEK_SET:
		Seek(fileptr,position,OFFSET_BEGINNING);
		break;
	case SEEK_CUR:
		Seek(fileptr,position,OFFSET_CURRENT);
		break;
	case SEEK_END:
		Seek(fileptr,position,OFFSET_END);
		break;
	}
	return 0L;
}


/* Get char from stdio  */
/* timeout is in micros */

/* AINA PALAUTETAAN saatujen merkkien määrä tai -1==FATAL ERROR */
/* myös jos timeout tulee ennen kuin max on luettu! */
/* JOS timeout==0: lue heti max size merkkiä, kuitenkin puskuri tyhjäksi */
/* palauta saatujen merkkien määrä */

long __saveds __asm c_sread(register __a0 char *buffer,
							register __d0 long size,
							register __d1 long timeout)
{	int chars=0,c;

	do
	{
		if(WaitForChar(Input(),timeout))
		{
			c=Read(Input(),buffer+chars,size-chars);
			if(c<=0)		return -1;	/* carrier lost? EOF? breaked? */
			chars+=c;
			if(!timeout)	return chars;
		}
		else
		{
			return chars;
		}
	}
	while(chars<size);
	return chars;
}

/* Put string to stdout */

long __saveds __asm c_swrite(register __a0 char *buffer,
							 register __d0 long size)
{
	return Write(Output(),buffer,size);
}

/* Flush stdin buffer*/

void __saveds c_sflush(void)
{	char flushbuffer[128],count=0;

	while(WaitForChar(Input(),0) && ++count<20 && Read(Input(),flushbuffer,128)>0);
}

long __saveds c_chkabort(void)
{   long state=iostatus();

	if(state==-1)   return 0;		/* ACTION_QUERY not implemented */
	if(state & (1<<5))  return -1;	/* carrier lost */
	if(state & (1<<10)) return -1;	/* break received */
	return 0;
}

/*
long __saveds c_ffirst(char *buf, char *pattern)
{
	return 0L;
}

long __saveds c_fnext(long fstate, char *buf, char *template)
{
	return 0L;
}
*/

/* query/set serial params */
long __saveds __asm c_setserial(register __d0 long newstatus)
{
	if(newstatus==-1L)
	{
		return 0x00040094;
		/* 4800bps, parity off, 7WIRE, RAD_BOOGIE, XON/XOFF disabled, 8bits */
	}
	else
	{
		return -1L;
	}
}

/* check miscellaneous stuff */
void __saveds c_chkmisc(void)		/* not used ! */
{;
}

/* query serial input buffer */
long __saveds c_squery(void)
{
	if(WaitForChar(Input(),0))
	{
		return IoErr();
	}
	return 0;
}

/* delete a file */

long __saveds __asm c_unlink(register __a0 char *name)
{
	return DeleteFile(name);
}

long __saveds __asm c_options(register __d0 long n,
							  register __a0 struct xpr_option *opt[])
{
	return 0;	/* not used ! */
}


long __saveds __asm c_gets(register __a0 char *prompt,
						   register __a1 char *buffer)
{
	buffer[0]='\0';
	return 0;
}

void __saveds __asm c_update(register __a0 struct XPR_UPDATE *ud)
{	long a=ud->xpru_updatemask;
	static int count=0;

	if(a & XPRU_FILENAME)
	{
		strcpy(name,ud->xpru_filename);
		fprintf(err,"Filename: %s\n",name);
	}
	if(a & XPRU_FILESIZE)
	{
		size=ud->xpru_filesize;
		fprintf(err,"Filesize: %ld\n",size);
	}

	if(a & XPRU_BYTES)
		bytes=ud->xpru_bytes;
	if(a & XPRU_EXPECTTIME)
		strcpy(expect,ud->xpru_expecttime);
	if(a & XPRU_ELAPSEDTIME)
		strcpy(elapsed,ud->xpru_elapsedtime);
	if(a & XPRU_DATARATE)
		cps=ud->xpru_datarate;
	if(++count>4)
	{
		count=0;
		fprintf(err,"  %ld/%ld %ld %s %s\r",bytes,size,cps,elapsed,expect);
	}
}


void init_xprio(int batch)
{
	memclr((void*) &io, sizeof(io));

#pragma msg 147 ignore push
	io.xpr_filename= NULL;
	io.xpr_fopen=	(void *) c_fopen;
	io.xpr_fclose=	(void *) c_fclose;
	io.xpr_fread=	(void *) c_fread;
	io.xpr_fwrite=	(void *) c_fwrite;
	io.xpr_sread=	(void *) c_sread;
	io.xpr_swrite=	(void *) c_swrite;
	io.xpr_sflush=	(void *) c_sflush;
	io.xpr_update=	(void *) c_update;
	io.xpr_chkabort=(void *) c_chkabort;
/*	io.xpr_chkmisc=	(void *) c_chkmisc;*/
/*	io.xpr_gets=	(void *) c_gets;*/
	io.xpr_setserial=(void*) c_setserial;
	io.xpr_ffirst=	NULL;
	io.xpr_fnext=	NULL;
	io.xpr_finfo=	(void *) c_finfo;
	io.xpr_fseek=	(void *) c_fseek;

	io.xpr_extension=	3L;

/*	io.xpr_options=	(void *) c_options;*/
	io.xpr_unlink=	(void *) c_unlink;
	io.xpr_squery=	(void *) c_squery;
}


int caller(char *host)
{	int i;
	unsigned char temp[200];
	int c;
	long oldlock,lock;
	FILE *fp;

/* Login into the system */
	if(fp=fopen("AXsh:etc/adm/netlog","a"))
	{
		fprintf(fp,"100 %s",get_time());
		fclose(fp);
	}
	printf("\r");
	fflush(stdout);
	Delay(150);
	i=c=0;
	while(i<20)
	{
		if(c)
		{
			printf("%s\r",Host);
			fflush(stdout);
			c=0;
		}
		if(getline(temp,100,3000))
		{
			c=1;
			i++;
		}
		if(!strncmp(temp+1,"ogin:",5))
			c=1;
		if(!strncmp(temp+1,"assword:",8) && c)
			break;
	}
	if(i==15)	return -1;

	printf("%s\r",Pass);
	fflush(stdout);
	fprintf(err,"Password sent\n");
	i=0;
	while(i<15)
	{
		if(getline(temp,100,3000))
		{
			i++;
			if(i>13)
			{
				printf("\r");
				fflush(stdout);
			}
		}
		else
		{
			if(!strncmp(temp,"1.",2) || temp[1]=='.' || !strncmp(temp+strlen(temp)-2,"> ",2))
				break;
		}
	}

	printf("\rnet $user\r");
	fflush(stdout);
	fprintf(err,"Sent net-command\n");

	Delay(25);
	while(!getline(temp,50,3000));	/* get the echoed net-command */

/* caller sends first... */
/* start sending mail */

	sprintf(temp,"%s%s",Mailhome,host);
	if(lock=Lock(temp,ACCESS_READ))
	{
		UnLock(lock);

		fprintf(err,"Packing mail\n");
		sprintf(temp,"c:LhA >NIL: a %spacket.LHA %s%s",Tmpdir,Mailhome,host);
		fprintf(err,"%s\n",temp);
		Execute(temp,NULL,NULL);	/* pack system mailbox */

		if(sendid(RX,sendidto))
		{
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		fprintf(err,"Sending mail\n");
		io.xpr_filename=XPRINIT;
		if(!XProtocolSetup(&io))
		{
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		sprintf(temp,"%spacket.LHA",Tmpdir);
		io.xpr_filename=temp;
		if(XProtocolSend(&io))
		{
			sprintf(temp,"%s%s",Mailhome,host);
			DeleteFile(temp);
			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"201 sz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}
		}
		sprintf(temp,"%spacket.LHA",Tmpdir);
		DeleteFile(temp);
	}
	else
	{
		if(sendid(SKIP,sendidto))
			return -1;
	}
	fprintf(err,"\nMail sent\n");

/* start receiving mail */

	fprintf(err,"Waiting for RX/SKIP\n");

	if(!(c=receiveid(receiveidto)))
		return -1;
	if(c==RX)
	{
		sprintf(temp,"%s%s",XPRINIT,Tmpdir);
		fprintf(err,"Receiving mail\n");
		io.xpr_filename=temp;
		if(!XProtocolSetup(&io))
			return -1;

		io.xpr_filename="";
		if(XProtocolReceive(&io))
		{
			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"200 rz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}

			/* we trust that mailhome can be locked */
			oldlock=CurrentDir(Lock(Mailhome,ACCESS_READ));
			fprintf(err,"\nUnpacking mail\n");
			sprintf(temp,"c:LhA >NIL: x %spacket.LHA",Tmpdir);
			fprintf(err,"%s\n",temp);
			Execute(temp,NULL,NULL);
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);

			if(fp=fopen(Host,"r"))
			{
				fclose(fp);
				fprintf(err,"AXsh:bin/mailserver >NIL:\n");
				Execute("AXsh:bin/mailserver >NIL:",NULL,NULL);
			}
			UnLock(CurrentDir(oldlock));
		}
	}
	else
		fprintf(err,"No mail\n");

/* start news-packing */

	fprintf(err,"Collecting news\n");
	sprintf(temp,"AXsh:bin/rn >NIL: net %s pack",host);
	fprintf(err,"%s\n",temp);
	Execute(temp,NULL,NULL);

/* start sending news */
	sprintf(temp,"%s%s",Newshome,host);
	if(lock=Lock(temp,ACCESS_READ))
	{
		UnLock(lock);

		fprintf(err,"Packing news\n");
		sprintf(temp,"c:LhA >NIL: a %spacket2.LHA %s%s",Tmpdir,Newshome,host);
		fprintf(err,"%s\n",temp);
		Execute(temp,NULL,NULL);

		if(sendid(RX,sendidto))
		{
			sprintf(temp,"%spacket2.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		fprintf(err,"Sending news\n");
		io.xpr_filename=XPRINIT;
		if(!XProtocolSetup(&io))
		{
			sprintf(temp,"%spacket2.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		sprintf(temp,"%spacket2.LHA",Tmpdir);
		io.xpr_filename=temp;
		if(XProtocolSend(&io))
		{
			sprintf(temp,"%s%s",Newshome,host);
			DeleteFile(temp);	/* if packet was sent OK, delete original */

			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"201 sz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}
		}
		sprintf(temp,"%spacket2.LHA",Tmpdir);
		DeleteFile(temp);
	}
	else
	{
		if(sendid(SKIP,sendidto))
			return -1;
	}
	fprintf(err,"\nNews sent\n");

/* start receiving news */

	fprintf(err,"Waiting for RX/SKIP\n");
	if(!(c=receiveid(receiveidto)))
		return -1;
	if(c==RX)
	{
		sprintf(temp,"%s%s",XPRINIT,Tmpdir);
		fprintf(err,"Receiving news\n");
		io.xpr_filename=temp;
		if(!XProtocolSetup(&io))
			return -1;

		io.xpr_filename="";
		i=XProtocolReceive(&io);

		if(fp=fopen("AXsh:etc/adm/netlog","a"))
		{
			fprintf(fp,"200 rz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
			fclose(fp);
		}
		printf("exit\n");
		fflush(stdout);
		fprintf(err,"\nexiting %s\n",host);
		hangup(108,host);
		if(fp=fopen("AXsh:etc/adm/netlog","a"))
		{
			fprintf(fp,"106 %s\n",get_time());
			fclose(fp);
		}

		if(i)
		{
			/* we trust that newshome can be locked */
			oldlock=CurrentDir(Lock(Newshome,ACCESS_READ));
			fprintf(err,"Unpacking news\n");
			/* delete the old packet - if any, so lha wont ask for overwrite.. */
			DeleteFile(Host);
			sprintf(temp,"c:LhA >NIL: x %spacket2.LHA",Tmpdir);
			fprintf(err,"%s\n",temp);
			Execute(temp,NULL,NULL);
			sprintf(temp,"%spacket2.LHA",Tmpdir);
			DeleteFile(temp);
			if(lock=Lock(Host,ACCESS_READ))
			{
				UnLock(lock);
				sprintf(temp,"AXsh:bin/rn >NIL: net %s unpack",host);
				fprintf(err,"%s\n",temp);
				Execute(temp,NULL,NULL);
			}
			UnLock(CurrentDir(oldlock));
		}
	}
	else
	{
		fprintf(err,"No news\n");
		printf("exit\n");
		fprintf(err,"\nexiting %s\n",host);
		hangup(108,host);
		if(fp=fopen("AXsh:etc/adm/netlog","a"))
		{
			fprintf(fp,"106 %s\n",get_time());
			fclose(fp);
		}
	}
	return 0;
}

int receiver(char *host)
{	unsigned char temp[200];
	long oldlock,lock;
	FILE *fp;
	int error=0, c;

/* start packing and receiving.. */
/* start receiving mail */

	fprintf(err,"Waiting for RX/SKIP\n");
	if(!(c=receiveid(receiveidto)))
		return -1;
	if(c==RX)
	{
		sprintf(temp,"%s%s",XPRINIT,Tmpdir);
		fprintf(err,"Receiving mail\n");
		io.xpr_filename=temp;
		if(!XProtocolSetup(&io))
			return -1;

		io.xpr_filename="";
		if(XProtocolReceive(&io))
		{
			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"200 rz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}

			/* we trust that mailhome can be locked */
			oldlock=CurrentDir(Lock(Mailhome,ACCESS_READ));
			fprintf(err,"\nUnpacking mail\n");
			sprintf(temp,"c:LhA >NIL: x %spacket.LHA",Tmpdir);
			fprintf(err,"%s\n",temp);
			Execute(temp,NULL,NULL);
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);

			if(lock=Lock(Host,ACCESS_READ))
			{
				UnLock(lock);
				fprintf(err,"AXsh:bin/Mailserver >NIL:\n");
				Execute("AXsh:bin/mailserver >NIL:",NULL,NULL);
			}
			UnLock(CurrentDir(oldlock));
		}
	}
	else
		fprintf(err,"No mail\n");

/* start sending mail */

	sprintf(temp,"%s%s",Mailhome,host);
	if(lock=Lock(temp,ACCESS_READ))
	{
		UnLock(lock);
		fprintf(err,"Packing mail\n");
		sprintf(temp,"c:LhA >NIL: a %spacket.LHA %s%s",Tmpdir,Mailhome,host);
		fprintf(err,"%s\n",temp);
		Execute(temp,NULL,NULL);	/* pack system mailbox */

		if(sendid(RX,sendidto))
		{
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		fprintf(err,"Sending mail\n");
		io.xpr_filename=XPRINIT;
		if(!XProtocolSetup(&io))
		{
			sprintf(temp,"%spacket.LHA",Tmpdir);
			DeleteFile(temp);
			return -1;
		}

		sprintf(temp,"%spacket.LHA",Tmpdir);
		io.xpr_filename=temp;
		if(XProtocolSend(&io))
		{
			sprintf(temp,"%s%s",Mailhome,host);
			DeleteFile(temp);

			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"201 sz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}
		}
		sprintf(temp,"%spacket.LHA",Tmpdir);
		DeleteFile(temp);
	}
	else
	{
		if(sendid(SKIP,sendidto))
			return -1;
	}

/* start news-packing */

	fprintf(err,"\nCollecting news\n");
	sprintf(temp,"AXsh:bin/rn >NIL: net %s pack",host);
	fprintf(err,"%s\n",temp);
	Execute(temp,NULL,NULL);

/* start receiving news */

	fprintf(err,"Waiting for RX/SKIP\n");
	if(!(c=receiveid(receiveidto)))
		return -1;
	if(c==RX)
	{
		sprintf(temp,"%s%s",XPRINIT,Tmpdir);
		fprintf(err,"Receiving news\n");
		io.xpr_filename=temp;
		if(!XProtocolSetup(&io))
			return -1;

		io.xpr_filename="";
		if(XProtocolReceive(&io))
		{
			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"200 rz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}

			/* we trust that newshome can be locked */
			oldlock=CurrentDir(Lock(Newshome,ACCESS_READ));
			fprintf(err,"Unpacking news\n");
			/* delete the old packet - if any, so lha wont ask for overwrite.. */
			DeleteFile(Host);
			sprintf(temp,"c:LhA >NIL: x %spacket2.LHA",Tmpdir);
			fprintf(err,"%s\n",temp);
			Execute(temp,NULL,NULL);

	/* we will distribute it later.. */
			UnLock(CurrentDir(oldlock));
		}
		sprintf(temp,"%spacket2.LHA",Tmpdir);
		DeleteFile(temp);
	}
	else
	{
		fprintf(err,"No news\n");
	}

/* start sending news */

	sprintf(temp,"%s%s",Newshome,host);
	if(lock=Lock(temp,ACCESS_READ))
	{
		UnLock(lock);
		fprintf(err,"Packing news\n");
		sprintf(temp,"c:LhA >NIL: a %spacket2.LHA %s%s",Tmpdir,Newshome,host);
		fprintf(err,"%s\n",temp);
		Execute(temp,NULL,NULL);

		if(sendid(RX,sendidto))
		{
			sprintf(temp,"%spacket2.LHA",Tmpdir);
			DeleteFile(temp);
			error=-1;
			goto goout;
		}

		fprintf(err,"Sending news\n");
		io.xpr_filename=XPRINIT;
		if(!XProtocolSetup(&io))
		{
			sprintf(temp,"%spacket2.LHA",Tmpdir);
			DeleteFile(temp);
			error=-1;
			goto goout;
		}

		sprintf(temp,"%spacket2.LHA",Tmpdir);
		io.xpr_filename=temp;
		if(XProtocolSend(&io))
		{
			sprintf(temp,"%s%s",Newshome,host);
			DeleteFile(temp);	/* if the packet was sent right, delete original */

			if(fp=fopen("AXsh:etc/adm/netlog","a"))
			{
				fprintf(fp,"201 sz: %ld bytes, %ld cps, %s elapsed : %s\n",size,cps,elapsed,name);
				fclose(fp);
			}
		}
		sprintf(temp,"%spacket2.LHA",Tmpdir);
		DeleteFile(temp);
	}
	else
	{
		if(sendid(SKIP,sendidto))
		{
			error=-1;
			goto goout;
		}
	}

	hangup(109,host);

goout:
	sprintf(temp,"%s%s",Newshome,Host);	/* here we distribute the news.. */
	if(lock=Lock(temp,ACCESS_READ))
	{
		UnLock(lock);
		fprintf(err,"\nRnnet\n");
		sprintf(temp,"AXsh:bin/rn >NIL: net %s unpack",host);
		fprintf(err,"%s\n",temp);
		Execute(temp,NULL,NULL);
	}
	return error;
}


int	getline(char *line,int maxlen,int timeout)
{
	int i=0,ti=1000*timeout;

	if(carrier_lost())
		return -1;
	do
	{
		if(WaitForChar(Input(),ti) && Read(Input(),line+i,1))
		{
			if(line[i]==0x0a)	break;
			if(line[i]==0x08 && i)	i--;
			else
				if(line[i]!=0x0d)	i++;
		}
		else
		{
			line[i]=0;
			return -1;
		}
	}
	while(i<maxlen-1);
	line[i]=0;
	return 0;
}


void read_config()
{
	FILE *handle;
	char line[LEN];
	register int i=0,found=0;

	if(handle=fopen("AXsh:etc/rc","rb"))	/* luetaan config */
	{
		while(fgets(line,LEN,handle))
		{
			i=strlen(line);
			if(line[i-1]==0x0a || line[i-1]==0x0d)
				line[i-1]='\0';

			if(found==0)
			{
				if(!strncmp(line,"%thismachine:",13))
					found=1;
				if(!strncmp(line,"%mail:",6))
					found=2;
				if(!strncmp(line,"%news:",6))
					found=3;
				if(!strncmp(line,"%hub:",5))
					found=4;
				if(!strncmp(line,"%password:",10))
					found=5;
				if(!strncmp(line,"%tempdir:",9))
					found=6;
				if(!strncmp(line,"%netsendto:",11))
					found=7;
				if(!strncmp(line,"%netreceiveto:",14))
					found=8;
			}
			else
			{
				if(found==1) strcpy(Host,line);
				if(found==2) strcpy(Mailhome,line);
				if(found==3) strcpy(Newshome,line);
				if(found==4) strcpy(Hub,line);
				if(found==5) strcpy(Pass,line);
				if(found==6) strcpy(Tmpdir,line);
				if(found==7) sendidto = atoi(line);
				if(found==8) receiveidto = atoi(line);
				found=0;
			}
		}
		fclose(handle);
	}
	if(handle=fopen("AXsh:etc/rc.mail","rb"))	/* luetaan config */
	{
		while(fgets(line,LEN,handle))
		{
			i=strlen(line);
			if(line[i-1]==0x0a || line[i-1]==0x0d)
				line[i-1]='\0';

			if(found==0)
			{
				if(!strncmp(line,"%mail:",6))
					found=2;
			}
			else
			{
				if(found==2) strcpy(Mailhome,line);
				found=0;
			}
		}
		fclose(handle);
	}
	if(handle=fopen("AXsh:etc/rc.news","rb"))	/* luetaan config */
	{
		while(fgets(line,LEN,handle))
		{
			i=strlen(line);
			if(line[i-1]==0x0a || line[i-1]==0x0d)
				line[i-1]='\0';

			if(found==0)
			{
				if(!strncmp(line,"%news:",6))
					found=3;
			}
			else
			{
				if(found==3) strcpy(Newshome,line);
				found=0;
			}
		}
		fclose(handle);
	}
	if(sendidto < 120)
	{
		sendidto = 120;
	}
	if(receiveidto < 300)
	{
		receiveidto = 300;
	}
	makepath(Mailhome,Mailhome);
	makepath(Newshome,Newshome);
	makepath(Tmpdir,Tmpdir);
}

int sendid(unsigned char ID,int acktime)
{	unsigned char c;
	int ti=0;

	c=ID;
	Write(Output(),&c,1);

	while(ti<acktime)
	{
		if(carrier_lost())
		{
			fprintf(err,"Carrier lost in sendID\n");
			return -1;
		}

		if(WaitForChar(Input(),5000000))
		{
			if(Read(Input(),&c,1) && (c==(ID^ACKN)))
				return 0;		/* OK.. */
		}
		c=ID;
		Write(Output(),&c,1);	/* send again */
		ti+=5;
	}
	fprintf(err,"Timeout in sendID\n");
	return -1;					/* timeout */
}

int receiveid(int time)
{	unsigned char c,id=0;
	int ti=0;

	while(ti<time)
	{
		if(carrier_lost())
		{
			fprintf(err,"Carrier lost in receiveID\n");
			return -1;
		}

		if(WaitForChar(Input(),10000000))
		{
			if(Read(Input(),&c,1) && (c==RX || c==SKIP) && !id)
			{
				id=c;
				c=id^ACKN;
				Write(Output(),&c,1);

				while(1)
				{
					if(carrier_lost())
					{
						fprintf(err,"Carrier lost in receiveID\n");
						return -1;
					}

					if(WaitForChar(Input(),10000000))
					{
						Read(Input(),&c,1);
						if(c==id)
						{
							c=id^ACKN;
							Write(Output(),&c,1);
						}
					}
					else
						return id;			/* ok, he's not sending anymore */
				}
				break;
			}
		}
		ti+=10;
	}
	fprintf(err,"Timeout in receiveID\n");
	return 0;				/* timeout */
}


void hangup(int which,char *who)
{	FILE *fp;

	setmode(MODE_RAW);
	printf("exit\n");
	fflush(stdout);

	Delay(180);
	Write(Output(),"+++",3);
	Delay(200);
	Write(Output(),"\r",1);
	Delay(25);
	Write(Output(),"ath0s0=0\r",9);
	Delay(100);

	if(Online)
	{
		if(fp=fopen("AXsh:etc/adm/netlog","a"))
		{
			DateStamp(&outtime);
			fprintf(fp,"%03d %d minutes with %s\n",which,
					(outtime.ds_Days-intime.ds_Days)*1440+outtime.ds_Minute-intime.ds_Minute,
					who
					);
			fclose(fp);
		}
		Online=FALSE;
	}
	setmode(MODE_CONSOLE);
}


char *get_time()
{	long joo;

	joo=time(&joo);
	return asctime(localtime(&joo));
}

void main(int argc,char *argv[])	/* 'net machine-name' in axsh, 'net' to caller */
{
	FILE *fp;

	DateStamp(&intime);
	Online=TRUE;
	err=fopen("raw:0/0/400/160/Net Progress/INACTIVE","w");

	if((XProtocolBase=(struct Library *)OpenLibrary(XPRNAME,0)))
	{
		init_xprio(FALSE);

		io.xpr_filename="";	/* Actually we only check that everything is ok.*/
		if(XProtocolSetup(&io))
		{
			setmode(MODE_RAW | MODE_NOCRLF);
			io.xpr_filename="";

			read_config();	/* setting up.. */
			oldpri=SetTaskPri(FindTask(0L),0);

			if(argc>1)
			{
				if(receiver(argv[1]))
					hangup(109,argv[1]);
			}
			else
			{
				if(caller(Hub))
				{
					if(fp=fopen("AXsh:etc/adm/netlog","a"))
					{
						fprintf(fp,"105 %s\n",get_time());
						fclose(fp);
					}
				}
			}

			SetTaskPri(FindTask(0L),oldpri);
			XProtocolCleanup(&io);
			setmode(MODE_CONSOLE);
		}
		else
			fprintf(err,"Setup error\n");
		CloseLibrary(XProtocolBase);
	}
	else
	{
		fprintf(err,"\aCannot open %s\n",XPRNAME);
	}

	fclose(err);
	exit(0);
}

