/*
 *	Miscellaneous routines and messages for OKONNEKT.
 *	In general, what you will find here are routines that the Opus
 *	routines need from other Opus modules.
 */
#include "xfer.h"
#include "com.h"
#include <dos.h>
#include <ctype.h>
#include <stdio.h>
#include <varargs.h>

char e_input[255];
char *Loc_msg = e_input;

char *IDUNNO_msg = "Can you hear me, Major Tom?";
char *FLAGGING_msg = "Flagging %s as sent";
char *NOTSENT_msg = "File %s not sent";
char *TRUNC_msg = "File %s truncated";
char *MEMOVFL_msg = "Memory Overflow";
char *CAN_msg = "Transfer cancelled";
char *KBD_msg = "Keyboard Escape";
char *TIME_msg = "Timeout";
char *CARRIER_msg = "Lost Carrier";
char *READ_msg = "File Read";
char *SEEK_msg = "File Seek";
char *NAK_msg = "NAK";
char *FUBAR_msg = "Too many errors";
char *CMPL_msg = "Bad block complement";
char *CRC_msg = "CRC";
char *EOT_msg = "EOT";
char *SYNC_msg = "Out of Sync";
char *CHK_msg = "Checksum";
char *SHRT_msg = "Short block";
char *IO_msg = "I/O Error";
char *CREATE_msg = "Create";
char *CLOSE_msg = "Close";
char *UNLINK_msg = "Unlink";
char *OPEN_msg = "Open";
char *WRITE_msg = "Write";
char *NOTHING_msg = "Nothing transferred";
char *local_CEOL = "\033[K";


dexists(filename)
char *filename;
{
struct FILEINFO dta;
return (!dfind(&dta,filename,0));
}

dfind (dta, name, times)
struct FILEINFO *dta;
char *name;
int times;
{
	union REGS r;

	r.x.dx = dta;
	r.h.ah = 0x1a;
	intdos (&r, &r);
	r.x.bx = 0;
	r.x.cx = ~0x08;
	r.x.dx = name;
	r.x.si = 0;
	r.x.di = 0;
	if (times == 0)
		{
		r.h.ah = 0x4e;
		intdos (&r, &r);
		dta->nill = '\0';
		if (r.x.cflag != 0)
			{
			dta->name[0] = '\0';
			return (1);
			}
		return (0);
		}
	else
		{
		r.h.ah = 0x4f;
		intdos (&r, &r);
		dta->nill = '\0';
		if (r.x.cflag != 0)
			{
			dta->name[0] = '\0';
			return (1);
			}
		return (0);
		}
	}


status_line(va_alist)
va_dcl
{
char *fmt;
va_list arg_ptr;
extern int errno;

va_start(arg_ptr);
fmt = va_arg(arg_ptr, char *);
errno = 0;
WRITE_ANSI('\r');
WRITE_ANSI('\n');
vprintf(fmt,arg_ptr);
WRITE_ANSI('\r');
WRITE_ANSI('\n');
locate_x = wherex();
locate_y = wherey();
va_end(arg_ptr);
}

got_error(string1,string2)
char *string1,*string2;
{
extern int errno;
if (errno == 0x18)
	errno = 0;
if (errno != 0)
	{
	scr_printf("Can't ");
	scr_printf(string1);
	WRITE_ANSI(' ');
	scr_printf(string2);
	WRITE_ANSI('\n');
	errno = 0;
	return(1);
	}
return(0);
}

set_xy(string)
char *string;
{
if (*string != '\0')
	{
	WRITE_ANSI('\r');
	WRITE_ANSI('\n');
	scr_printf(string);
	}
locate_x = wherex();
locate_y = wherey();
}

message(string)
char *string;
{
gotoxy(locate_x,locate_y);
if (*string != '\0')
	scr_printf(string);
}

time_release()
{
}

n_disable()
{
}

adios(n)
int n;
{
MDM_DISABLE();
exit(n);
}

brk_disable()
{
}


fancy_str()
{
}

timer(interval)
int interval;
{
long timeout,timerset();
timeout = timerset (interval * 10);
while (!timeup(timeout))
	;
}

big_pause(secs)
int secs;
{
long timeout,timerset();
timeout = timerset (secs * 100);
while (!timeup(timeout))
	{
	if (CHAR_AVAIL())
		exit;
	}
}

unsigned int com_getc (t)
int t;
{
	unsigned char c;
	long t1;
	extern long timerset();

	if (CHAR_AVAIL())
		return (MODEM_IN());
	t1 = timerset (t * 100);
	while (!CHAR_AVAIL())
		{
		if (timeup (t1))
			{
			return (EOF);
			}
		}
	return (MODEM_IN());
	}



/* Z F R E E -- Return total number of free bytes on drive specified */

long zfree(drive)
char *drive;
{
	union REGS r;

	int driveno;
	long stat;

	if (drive[0] != '\0' && drive[1]== ':' )
		{
		driveno = islower(*drive) ? toupper(*drive) : *drive;
		driveno = driveno - 'A' + 1;
		}
	else
		driveno = 0;			/* Default drive	*/

	r.x.ax = 0x3600;			/* get free space	*/
	r.h.dl = driveno;			/* on this drive	*/
	int86(0x21,&r,&r);			/* go do it		*/

	if (r.x.ax == 0xffff)			/* error return??	*/
		return(0);

	stat = (long)r.x.dx			/* dx = clusters avail	*/
	     * (long)r.x.ax			/* ax = sectors/clust	*/
	     * (long)r.x.cx;			/* cx = bytes/sector	*/

	return(stat);
}

/*
 * This function calculates the CRC used by the XMODEM/CRC Protocol
 * The first argument is the current CRC accumulator
 * The second argument is the next byte to add into the CRC
 * The function returns an integer which contains the CRC.
 * The low order 16 bits are the coefficients of the CRC.
 */
unsigned int crc_update(crc, b)
unsigned int crc;
unsigned char b;
{
	register newcrc;
	int i;

	newcrc = crc ^ (int)b << 8;
	for (i = 0; i < 8; ++i)
		if (newcrc & 0x8000)
			newcrc = newcrc << 1 ^ 0x1021;
		else
			newcrc = newcrc << 1;
	return (newcrc & 0xFFFF);
}

scr_printf(string)
char *string;
{
	while (*string != 0)
		WRITE_ANSI(*string++);
}

void send_can()
   begin
   	int i;
      for(i=0; i<10; i++) SENDBYTE(CAN);
      for(i=0; i<10; i++) SENDBYTE(BS);
   end

