/*
	bbscport.c

*/

#include "bbscdef.h"
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef linux
#include "nolock.h"
#else
#include <sys/locking.h>
#endif
extern int no_cntrl_k;
extern int hold_off;
extern int toggle_hold;
extern unsigned int Zsec;

#define LASTDATE  " 05/05/89 "

#define PGMNAME "BBSCPORT "

char portin()		/* get one byte from the port */
{
	char byte;
	int byte0;
	unsigned int ssec, tsec, usec, vsec;
	int this_timer, wsec;
	if(toggle_hold) (void) sys_toggle();
	hold_off = TRUE;
	this_timer = which_timer;
	which_timer = 3;
	ssec = alarm(0);
	tsec = waittime;
	if(tsec > ssec)
		{
		tsec = ssec;
		which_timer = this_timer;
		}
	Zsec = ssec - tsec;
	alarm(tsec);
	byte0=cget();
	byte = (char)byte0;
	switch ( byte0 ) {
	
	case -1:
		fprintf(stderr,"cget() returns -1 -- ABORTING");
		exit(1);
	default:
		usec = alarm(0);
		which_timer = this_timer;
		wsec = ssec - (tsec - usec);
		if(wsec < 2 ) wsec = 2;
		vsec = wsec;
		alarm( vsec );
		hold_off = FALSE;
		if(toggle_hold) (void)sys_toggle();
		return(byte);
	}
}

char portin_chat()		/* get one byte from the port */
{
	char byte;
	int byte0;
	byte0=cget_chat();
	byte = (char)byte0;
	switch ( byte0 ) {
	
	case -1:
		fprintf(stderr,"cget() returns -1 -- ABORTING");
		exit(1);
	default:
		return(byte);
	}
}
portsin(buf,max)	/* get a line of input max. chars long */
int max ; char *buf ;
	{
	int cnt, byte ; char bytex ;
	cnt = 0;
	byte = FALSE;
	while (++cnt <= max && byte != '\r')
		{
		while((byte = (int)portin()) < ' ' || byte > '}')
			{
			if( byte == 127) byte = '\b';
			if (byte == '\r') { break ; } /* carriage return */
			if (byte == '\b' && cnt > 1)	/* backspace */
				{
				portout(byte);
				portout(' ');
				portout(byte);
				*buf--;	/* backout last char */
				cnt--;	/* decrement count too */
				}
			}
		if (byte != '\r')
			{
			*buf++ = byte;
			}
		portout(byte);	/* echo good chars only */
		}
	*buf++	= '\0';			/* tag \0 on end */
	}
portsinz(buf,max)	/* get a line of input max. chars long */
int max ; char *buf ;
	{
	int cnt, byte ; char bytex ;
	cnt = 0;
	byte = FALSE;
	while (++cnt <= max && byte != '\r')
		{
		while((byte = (int)portin()) < ' ' || byte > '}')
			{
			if (byte == 127) byte = '\b';
			if (byte == '\r') { break ; } /* carriage return */
			if (byte == '\b' && cnt > 1)	/* backspace */
				{
				portout(byte);
				portout(' ');
				portout(byte);
				*buf--;	/* backout last char */
				cnt--;	/* decrement count too */
				}
			}
		if (byte != '\r')
			{
			*buf++ = byte;
			}
		portout('_');	/* echo an underscore  */
		}
	*buf++	= '\0';			/* tag \0 on end */
	}
portsinm(buf,max,buf1)	/* get a line of input max. chars long */
int max;
char *buf, *buf1;
	{
	int cnt, byte ; char bytex ;
	int  new_max;
	cnt = 0;
	new_max = max;
	byte = FALSE;
	while (++cnt <= new_max && byte != '\r')
		{
		while((byte = (int)portin()) < ' ' || byte > '}')
			{
			if (byte == 127) byte = '\b';
			if (byte == '\r') { break ; } /* carriage return */
			if (byte == '\b' && cnt > 1)	/* backspace */
				{
				portout(byte);
				portout(' ');
				portout(byte);
				*buf--;	/* backout last char */
				cnt--;	/* decrement count too */
				}
			if (byte == '\b' && cnt == 1 && in_the_buffer > 0)
				{
				portout(byte);
				portout(' ');
				portout(byte);
				in_the_buffer--;
				new_max++;
				buf1[in_the_buffer] = '\0';
				}

			}
		if (byte != '\r')
			{
			*buf++ = byte;
			}
		portout(byte);	/* echo good chars only */
		}
	*buf++	= '\0';			/* tag \0 on end */
	}


portsin_cmp(buf,max,cmp_str)	/* get a line of input max. chars long */
int max ; char *buf , *cmp_str;
	{
	int cnt, byte ; char bytex ;
	char *result;
	cnt = 0;
	byte = FALSE;
	while (++cnt <= max && byte != '\r')
		{
		while((byte = (int)portin()) < ' ' || byte > '}')
			{
			if (byte == 127) byte = '\b';
			if (byte == '\r') { break ; } /* carriage return */
			if (byte == '\b' && cnt > 1)	/* backspace */
				{
				portout(byte);
				portout(' ');
				portout(byte);
				*buf--;	/* backout last char */
				cnt--;	/* decrement count too */
				}
			}
		if (byte != '\r')
			{
			if(cnt == 1)
				{
				result = strchr(cmp_str,byte);
				if(result != NULL)		
					{
					*buf++ = byte;
					portout(byte);
					*buf++ = '\0';
					return;
					}
				}
			*buf++ = byte;
			}
		portout(byte);	/* echo good chars only */
		}
	*buf++	= '\0';			/* tag \0 on end */
	}

portout(byte)		/* send one byte to the port */
char byte;		/* return CTL_K for those times want to check */
	{		/* if the person wants to stop sending        */
	char byte0 ;
 
	byte0 = byte ; write(STDOUT,&byte0,1) ; /* send the byte */
	if(if_monitor)
		{
		write(mon_handle,&byte0,1);
		}
	return(OK) ;
	}
  
portout_chat(byte)		/* send one byte to the port */
char byte;		/* return CTL_K for those times want to check */
	{		/* if the person wants to stop sending        */
	char byte0 ;
 
	byte0 = byte ; write(STDOUT,&byte0,1) ; /* send the byte */
	if(if_monitor)
		{
		write(mon_handle,&byte0,1);
		}
	return(OK) ;
	}
  
portsout(string)	/* send a string to the port */
char *string ;
	{
	char byte ;

	while (byte = (*string++))
		{
  		portout(byte) ;		/* send one byte at a time */
		}
	}

portsout_chat(string)	/* send a string to the port */
char *string ;
	{
	char byte ;

	while (byte = (*string++))
		{
  		portout_chat(byte) ;		/* send one byte at a time */
		}
	}
portlsout(string,len)  /* send a string to the port, pad to length */
char *string ; int len ;
	{
	char byte ;

	while (byte = (*string++))
		{
  		portout(byte) ;		/* send one byte at a time */
		len-- ;
		}
	while (len > 0) { portout(' ') ; len-- ; } /* pad with spaces */
	}

porttype(tbuf)		/* type a file to the port */
FILE	*tbuf ;
	{
	int byte ;
	int xp;
	if(xpert)xp = 10; else xp = 5;
	stop_that = FALSE;	/* reset switch */
	if(!no_cntrl_k) portsout("\r\nType CTL-K to skip this\r\n\n");
	lnctx=1;
	byte = 0;
	while (((byte = getc (tbuf)) != EOF) && (byte != CPMEOF))
		{
		if(byte == '\n')
			{
			portout('\r');
			if(toggle)
			{
				lnctx++;
				if ( lnctx == 23 )
					{
					portsout(CRLF);
					if(!no_cntrl_k)
						portsout("*** Depress a key to continue ( control-k to quit ) ........ ");
					else
						portsout("*** Depress a key to continue  ........ ");
					jnk[0] = portin();
					if (jnk[0] == CTL_K )
					{			  
						stop_that = TRUE;
					}
					portsout(CRLF);
					lnctx=1;
					}
			}
			}
		if ( isprint(byte) == 0  && isspace(byte) == 0 )
		{
			portsout(CRLF);
			portsout(CRLF);
			portsout(CRLF);
			portsout("A non-printable character has been detected!");
			portsout(CRLF);
			portsout("This is probably NOT an ASCII file!");
			portsout(CRLF);
			portsout(CRLF);
			portsout(CRLF);
			stop_that = FALSE;
			return;
		}
		portout(byte);
		if (stop_that)		 /* received ctl-K or K */
			{
			portsout(CRLF);
			stop_that = FALSE;	/* reset switch */
			return;			/* nuf's enough */
			}
		}
	if(toggle && !no_cntrl_k && ( lnctx > xp ))
		{
		portsout(CRLF);
		portsout("*** Depress a key to continue ........ ");
		jnk[0] = portin();
		portsout(CRLF);
		}
	}

portinit()
	{
		setraw();
	}
	/* set raw mode for this terminal 
	struct sgttyb arg;
	ioctl (STDIN, TIOCGETP, &arg);
	arg.sg_flags |= RAW ;
	arg.sg_flags &= ~ECHO;
	ioctl (STDIN, TIOCSETP, &arg);
	}
*/

portrst()
	{
		restore();
	}
	/* set raw mode for this terminal 
	struct sgttyb arg;
	ioctl (STDIN, TIOCGETP, &arg);
	arg.sg_flags &= ~RAW;
	arg.sg_flags |= ECHO ;
	ioctl (STDIN, TIOCSETP, &arg);
	}
*/

char gobble()				/* gobble up any answer */
	{
	int cnt = 0 ;
	while (cnt++ < 20) (void)portin() ;
	}
rewritx()
{
	FILE *scope;
	int fds, result;
	if((scope=fopen(USERS,"r+"))==NULL)
		{
		portsout("\n\rError opening USERS file!\n\r");
		exit(1);
		}
	fds = fileno(scope);
	rewind(scope);
	locking(fds, LK_LOCK, 0L);
	result=fseek(scope, save_d_pos, 0);
	rewrtuser(scope);
	rewind(scope);
	locking(fds, LK_UNLCK, 0L);
	fclose(scope);
}
