/* this file is a test implementation of my suncom.opl program */
/* this is as close to a straight port as I can manage */
/* this program is sort of stateless appart from the fact that */
/* all file operations requite the path to be setup */
#include <plib.h>
#include <wlib.h>
#include <p_serial.h>

/* globals */
/* path strings */
TEXT sunname[200];
/* transmition strings */
TEXT hextxt[255], dectxt[255], suncmd[20], cmdlist[200];
/* temporary space */
TEXT tmp[300], wtmp[200] , ptmp[200] ;
/* index array for hex transformations */
TEXT hexarr[16] = "0123456789ABCDEF" ;
/* spacestr points to a sequence of spaces */
TEXT * spacestr ;
/* file handles */
INT  devh,  fileh ;
/* line counters */
INT lineid, sndline ;
/* window line counters point */
INT lineidpt, sndlinept ;
/* toggles */
INT vrb, tmode, scr;
/* window handles */
INT winline, winsnd, wintalk, winpath, wintog ;
/* window structures */
W_WINDATA wdline, wdsnd, wdtalk, wdpath, wdtog ;
/* graphics contexts */
UINT gcline, gcsnd, gctalk, gcpath, gctog ;
/* gc data setup structs */
G_GC gdline, gdsnd, gdtalk, gdpath, gdtog ;
/* input controler ??? */
INT linelen;
/* line widths */
#define HALFWIDTH 105
#define FULLWIDTH 225
/* define the number of chars to read in each send block */
#define MAXRD 120

/* debug defines */
/* define CALLDEBUG to track the function calls set it to be the delay in 1/10 seconds */
/*#define CALLDEBUG 5*/
/* define PATHDEBUG (as above) to track file names  */
/*#define PATHDEBUG 5*/
/* set linedbg (as above) to see what goes along the serial line */
/*#define LINEDEBUG 5*/

/* function definitions */
void main(void), getcmd(void), getline(void) ;
int ioget(void) ;
void setdefp(void) ,execmd(void), feedback(TEXT * msg), putline(TEXT * msg, int line) ;
void initlink(void), setline(void) ;
void initscr(void), wpath(void), wvb(void) ;
void wtm(void), wsc(void), wtalk( TEXT * msg), wline(void), wsnd(void), shutdown(void) ;
void initsys(void), sunvn(void), sunol(void), suniv(void), sunia(void), sunis(void), sunds(void);
void sunvb(void), sunsc(void), suntm(void), setp(void);
void updsp(void), sunsp(void), sundt(void);
void sunrp(void), sunep(void), exlist(void);
void sunlp (void), sundc(void), sunmd(void) ;
void sungf(void), sungfb(void), wsline(void), wssnd(void);
void sunpf (void), sunsl(void), sunrl(void), suntalk(TEXT * msg) ;
/* return status on files */
void sunft(void), sunrw(void), sunsz(void), sunti(void), sunwn(void), sunwy(void), suncs(void) ;
#ifdef CALLDEBUG
void calldbg (TEXT * msg) ;
void calldbg (TEXT * msg)
{
	p_print("Call %s\n", msg) ;
	p_sleep((ULONG) CALLDEBUG) ;
}
#endif
#ifdef PATHDEBUG
void pathdbg (TEXT * msg, TEXT * msg1) ;
void pathdbg (TEXT * msg, TEXT * msg1) 
{
	p_print(":%s: :%s:\n",msg, msg1) ;
	p_sleep((ULONG) PATHDEBUG) ;
}
#endif

 void main(void)
{
#ifdef CALLDEBUG
	calldbg("main") ;
#endif
	initsys() ;
	while (p_scmpi("dc", suncmd) != 0)
        {
		getcmd() ;
		execmd() ;
	}
	shutdown() ;
}

 void getcmd(void) 
{
#ifdef CALLDEBUG
	calldbg("getcmd") ;
#endif
	getline() ;
	suncmd[0] = dectxt[0] ;
	suncmd[1] = dectxt[1] ;
	suncmd[2] = 0 ;
}

 void getline(void) 
{
#ifdef CALLDEBUG
	calldbg("getline") ;
#endif
	linelen=ioget() ;
	if (linelen < 2)
		p_scpy(dectxt, "XX") ;
}

INT ioget(void)
{
	INT ret, cnt;
	UWORD v ;
	TEXT *ptr ;
#ifdef CALLDEBUG
	calldbg("ioget") ;
#endif

	putline(">",0) ;
	ret = p_read(devh, tmp, 3) ;
	/* mod from the origional code, we can do this differently */
	tmp[3] = 0;
	ptr = tmp + 1;
        p_stog(&ptr, &v, 16) ;
	cnt = (INT) v ;
	ret = p_read(devh, dectxt, cnt) ;
	dectxt[cnt] = 0 ;
#ifdef LINEDEBUG
	p_print("ioget, count = %d, data :%s:\n", cnt, dectxt) ;
	p_sleep((ULONG) LINEDEBUG) ;
#endif
	lineid ++ ;
	wline() ;
	return (ret) ;
}


 void execmd(void)
{


#ifdef CALLDEBUG
	calldbg("execmd");
#endif
	
	/* this section is rewritten to operate as a switch */

	if (p_scmpi("dc", suncmd) == 0) /* disconnect */
		sundc() ;
	else if (p_scmpi("vn", suncmd) == 0) /* version number */
		sunvn() ;
	else if (p_scmpi("ft", suncmd) == 0) /* file attributes */
		sunft() ;
	else if (p_scmpi("sz", suncmd) == 0) /* file size */
		sunsz() ;
	else if (p_scmpi("rw", suncmd) == 0) /* is file ro or rw */
		sunrw() ;
	else if (p_scmpi("sp", suncmd) == 0) /* set the path */
		sunsp() ;
	else if (p_scmpi("rp", suncmd) == 0) /* remove the file */
		sunrp() ;
	else if (p_scmpi("ti", suncmd) == 0) /* file modified time */
		sunti() ;
	else if (p_scmpi("lp", suncmd) == 0) /* list the path */
		sunlp() ;
	else if (p_scmpi("ep", suncmd) == 0) /* does the path exist ? */
		sunep() ;
	else if (p_scmpi("gf", suncmd) == 0) /* get file from the sun */
		sungf() ;
	else if (p_scmpi("pf", suncmd) == 0) /* put file to the sun */
		sunpf() ;
	else if (p_scmpi("md", suncmd) == 0) /* mkdir the path */
		sunmd() ;
	else if (p_scmpi("vb", suncmd) == 0) /* tobble verbose mode */
		sunvb() ;
	else if (p_scmpi("ds", suncmd) == 0) /* dump current strings */
		sunds() ;
	else if (p_scmpi("tm", suncmd) == 0) /* transfer mode */
		suntm() ;
	else if (p_scmpi("iv", suncmd) == 0) /* are we verbose ? */
		suniv() ;
	else if (p_scmpi("ia", suncmd) == 0) /* are we using ascii ? */
		sunia() ;
	else if (p_scmpi("sc", suncmd) == 0) /* toggle the screen mode */
		sunsc() ;
	else if (p_scmpi("is", suncmd) == 0) /* is the screen on ? */
		sunis() ;
	else if (p_scmpi("sl", suncmd) == 0) /* reset sent line counter */
		sunsl() ;
	else if (p_scmpi("rl", suncmd) == 0) /* reset recieved line counter */
		sunrl() ;
	else if (p_scmpi("ol", suncmd) == 0) /* are we online ? */
		sunol() ;
	else if (p_scmpi("dt", suncmd) == 0) /* display text in window */
		sundt() ;
	else if (p_scmpi("wy", suncmd) == 0) /* set rw mode on file */
		sunwy() ;
	else if (p_scmpi("wn", suncmd) == 0) /* set ro mode on file */
		sunwn() ;
	else if (p_scmpi("cs", suncmd) == 0) /* compute the checksum on a file */		suncs() ;
	else
		feedback("BADCMD") ;
}

 void feedback( TEXT  * msg)
{
#ifdef CALLDEBUG
	calldbg("feedback");
#endif
	tmp[0] = 0 ;

	p_scpy(tmp, "X") ;
        p_scat(tmp, msg) ;
	putline(tmp, 1) ;
}

 void putline(TEXT * msg, INT line) 
{
	INT i, len;
#ifdef CALLDEBUG
	calldbg("putline");
#endif
#ifdef LINEDEBUG
	p_print("putline :%s:\n", msg) ;
	p_sleep ((ULONG) LINEDEBUG) ;
#endif
	p_scpy(tmp, msg) ;
	/* put a CRLF pair at the end of the line and more the NULL allong */
	i = p_slen(tmp) ; 
	tmp[i] = 13 ;
	tmp[i+1] = 10 ;
	tmp[i+2] = 0 ;

	len = p_slen(tmp) ;
	if (len != i + 2)
	{
		suntalk("Error in printing lengths disagree\n") ;
		p_getch() ;
		p_exit(0) ;
	}
	p_write(devh, tmp, len) ;
	if (line)
	{
		sndline ++ ;
		wsnd() ;
	}
}

 void initlink(void)
{
	INT ret ;
#ifdef CALLDEBUG
	calldbg("initlink");
#endif
	ret = p_open(&devh, "TTY:A", -1) ;
	if (ret != 0)
	{
		suntalk("Error in opening device\n");
		p_getch() ;
		p_exit(0) ;
	}
	feedback("ONLINE") ;
}

 void setline(void)
{
	P_SRCHAR pchar ;
#ifdef CALLDEBUG
	calldbg("setline");
#endif

	/* get the serial port informatrion */
	p_iow(devh, P_FSENSE, &pchar) ;
	/* not force the data we need */
	pchar.tbaud = P_BAUD_9600 ;
	pchar.rbaud = P_BAUD_9600 ;
	pchar.frame = P_DATA_7 ;
	pchar.parity= P_PAR_EVEN || (! P_TWOSTOP) ;
	pchar.hand  = P_IGN_CTS ;
	p_iow(devh, P_FSET, &pchar) ;
}

 void initsys(void)
{
#ifdef CALLDEBUG
	calldbg("initsys") ;
#endif
	hextxt[0] = 0 ;
	dectxt[0] = 0 ;
	suncmd[0] = 0 ;
	spacestr =  "                                 " ;
        p_scpy(cmdlist, "dc,vn,sp,lp,ep,rp,gf,pf,md,vb,ds,tm,iv,ia,sc,is,sl,rl,ol,dt") ;
	vrb = 1 ;
	tmode = 0 ;
	lineid = 0 ;
	scr = 1 ;
	setdefp() ;
	initscr () ;
	initlink() ;
}

void setdefp(void)
{
#ifdef CALLDEBUG
	calldbg("setdefp") ;
#endif
	p_scpy(sunname, "M:") ;
}

void sunvn(void)
{
#ifdef CALLDEBUG
	calldbg("sunvn") ;
#endif
	suntalk ("Sunvn") ;
	feedback("2.17") ;
}

 void suniv(void)
{
#ifdef CALLDEBUG
	calldbg("suniv") ;
#endif
	suntalk ("Suniv") ;
	if (vrb)
		feedback("YES") ;
	else
		feedback("NO") ;
}

 void sunia (void)
{
#ifdef CALLDEBUG
	calldbg("sunia") ;
#endif
	suntalk ("Sunia") ;
	if (tmode)
		feedback("YES") ;
	else
		feedback("NO") ;
}

 void sunis (void)
{
#ifdef CALLDEBUG
	calldbg("sunis") ;
#endif
	suntalk ("Sunis") ;
	if (scr)
		feedback("YES") ;
	else
		feedback ("NO") ;
}

 void sunds (void)
{
#ifdef CALLDEBUG
	calldbg("sunds") ;
#endif
	suntalk ("Sunds") ;
	feedback ("START") ;
	p_scpy(tmp, "Path ") ;
	p_scat(tmp, sunname) ;
	putline(tmp,1) ;
	feedback ("END") ;
}

 void sunvb (void)
{
#ifdef CALLDEBUG
	calldbg("sunvb") ;
#endif
	if (vrb == 0)
	{
		vrb = 1 ;
		suntalk ("Sunvb on") ;
	}
	else
	{
		vrb = 0 ;
		suntalk("Sunvb off") ;
	}
	feedback("OK") ;
	wvb() ;
}

 void sunsc (void)
{
#ifdef CALLDEBUG
	calldbg("sunsc") ;
#endif
	if (scr == 0)
	{
		scr = 1;
		suntalk("Sunsc ON") ;
		wpath() ;
		wsc() ;
		wvb() ;
		wtm() ;
		wsline() ;
		wline() ;
		wssnd() ;
		wsnd() ;
		wCancelBusyMsg() ;
	}
	else
	{
		scr = 0 ;
		suntalk("Sunsc OFF") ;
		wSetBusyMsg("Display Updates OFF", W_CORNER_BOTTOM_LEFT | 0) ; 
	}
	feedback ("OK") ;
	wsc() ;
}

 void suntm (void)
{
#ifdef CALLDEBUG
	calldbg("suntm") ;
#endif
	if (tmode == 0)
	{
		feedback("BADMODE") ;
	}
	else
	{
		tmode = 0 ;
		suntalk ("BINARY") ;
	}
	feedback ("OK") ;
	wtm() ;
}

 void setpath(void)
{
#ifdef CALLDEBUG
	calldbg("setdefp") ;
#endif
	p_scpy(sunname, "M:") ;
}
 void sunsp(void)
{
#ifdef CALLDEBUG
	calldbg("sunsp") ;
#endif
	if (linelen < 4)
	{
		feedback("BADPARAM") ;
		return;
	}
	p_scpy(sunname, (dectxt + 3)) ;
	p_scpy(tmp, "Sunsp ") ;
	p_scat(tmp, sunname) ;
	suntalk (tmp) ;
	updsp() ;
	feedback("OK") ;
}

 void sundt(void)
{
#ifdef CALLDEBUG
	calldbg("sundt") ;
#endif
	if (linelen < 4)
	{
		feedback("BADPARAM") ;
		return ;
	}
	p_scpym(tmp, "Sundt ", (dectxt + 3)) ;
	suntalk (tmp) ;
	feedback ("OK") ;
}

 void updsp(void)
{
#ifdef CALLDEBUG
	calldbg("updsp") ;
#endif
	wpath() ;
}


 void sunep(void)
{
	P_INFO fstat ;
	INT ret ;
#ifdef CALLDEBUG
	calldbg("sunep") ;
#endif
	p_scpym(tmp, (TEXT * ) "Sunep ", sunname, NULL) ;
	suntalk(tmp) ;
	ret = p_finfo(sunname, &fstat) ;
	if (ret == 0)
		feedback ("YES") ;
	else
	{
		feedback ("NO") ;
	}
	
}

 void sunlp(void)
{
	INT tmpd ;
	P_INFO fstat ;
	P_FPARSE pstruct ;
	TEXT ltmp[300];
#ifdef CALLDEBUG
	calldbg("sunlp") ;
#endif
	p_scpym(tmp, "Sunlp ", sunname, NULL) ;
	suntalk(tmp) ;
	feedback("STARTLIST") ;
	if (p_open(&tmpd, sunname, P_FDIR) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	/* as we are now dealing with the full pathname we need to break it
	down to its parts and to then build it up to get the real pathname */
	/* allow wild cards */
	pstruct.flags = P_PWILD_ANY ;
	p_fparse(sunname, "", tmp, &pstruct) ;
	/* now build up the initial details from the structure , just use the device , directory
	though to save on bandwidth */
	/* set the appropriate nulls */
	tmp[pstruct.system+pstruct.device+pstruct.path] = '\0';
	p_scpy(ltmp, tmp+pstruct.system) ;
	while(p_iow(tmpd, P_FREAD, tmp, &fstat) != E_FILE_EOF)
	{
		/* we use ptmp here as we are alread using tmp and I dont like
		the idea of hacking the strings around as I'm not a good enough
		C programer to decide what will be overwritten when ! */
		p_scpym(ptmp, ltmp, tmp, NULL) ;
		putline(ptmp,1) ;
	}
	p_close(tmpd) ;
	feedback("ENDLIST") ;
}

 void sunrp(void)
{
#ifdef CALLDEBUG
        calldbg("sunrp") ;
#endif 
        p_scpym(tmp, "Sunrp ", sunname, NULL) ;
        suntalk(tmp) ;
        if (p_delete((TEXT * ) sunname) != 0)
        {
                feedback("BADRF") ;
        }
        else
        {
                feedback("OK") ;
        }
}
 void sunsz(void)
{
	P_INFO fileinfo ;
	TEXT tmp[100] ;
#ifdef CALLDEBUG
	calldbg("sunsz") ;
#endif
	p_scpym(tmp, "Sunsz ", sunname, NULL) ;
	suntalk(tmp) ;
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	tmp[p_ltob(tmp,fileinfo.size)] = 0 ;
	feedback(tmp) ;
}
 void sunti(void)
{
	P_INFO fileinfo ;
	TEXT tmp[100] ;
#ifdef CALLDEBUG
	calldbg("sunti") ;
#endif
	p_scpym(tmp, "Sunti ", sunname, NULL) ;
	suntalk(tmp) ;
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	/* this is the mod time in seconds, we can just transfer this
	   as unix uses time in seconds from midnight on  1/1/1970 */
	tmp[p_ltob(tmp,fileinfo.modst)] = 0 ;
	feedback(tmp) ;
}
 void sunwy(void)
{
	P_INFO fileinfo ;
#ifdef CALLDEBUG
	calldbg("sunwy") ;
#endif
	p_scpym(tmp, (TEXT * ) "Sunwy ", sunname, NULL) ;
	suntalk(tmp) ;
	/* does the file exist */
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	/* set the appropriate bit */
	if (p_sfstat(sunname, P_FAWRITE, P_FAWRITE) == 0)
	{
		feedback ("OK") ;
		return ;
	}
	else
	{
		feedback ("BADSET") ;
		return ;
	}
}
 void sunwn(void)
{
	P_INFO fileinfo ;
#ifdef CALLDEBUG
	calldbg("sunwn") ;
#endif
	p_scpym(tmp, (TEXT * ) "Sunwn ", sunname, NULL) ;
	suntalk(tmp) ;
	/* does the file exist */
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	/* set the appropriate bit */
	if (p_sfstat(sunname, 0, P_FAWRITE) == 0)
	{
		feedback ("OK") ;
		return ;
	}
	else
	{
		feedback ("BADSET") ;
		return ;
	}
}

 void sunrw(void)
{
	P_INFO fileinfo ;
	TEXT tmp[100] ;

#ifdef CALLDEBUG
	calldbg("sunrw") ;
#endif
	p_scpym(tmp, "Sunrw ", sunname, NULL) ;
	suntalk(tmp) ;
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	if (fileinfo.status & P_FAWRITE)
	{
		feedback("RW") ;
	}
	else
	{
		feedback("RO") ;
	}
}

 void sunft(void)
{
	P_INFO fileinfo ;
	TEXT tmp[100] ;
#ifdef CALLDEBUG
	calldbg("sunft") ;
#endif
	p_scpym(tmp, "Sunft ", sunname, NULL) ;
	suntalk(tmp) ;
	if (p_finfo(sunname,&fileinfo) != 0)
	{
		feedback("BADPATH") ;
		return ;
	}
	tmp[0] = 0 ;
	
	if (fileinfo.status & P_FADIR)
	{
		p_scat(tmp, "DIR ") ;
	}
	else if (fileinfo.status & P_FATEXT)
	{
		p_scat(tmp,"TEXT ") ;
	}
	else if (fileinfo.status & P_FAHIDDEN)
	{
		p_scat(tmp,"HIDDEN ") ;
	}
	else if (fileinfo.status & P_FASYSTEM)
	{
		p_scat(tmp,"SYSTEM ") ;
	}
	else if (fileinfo.status & P_FAVOLUME)
	{
		p_scat(tmp,"VOLUME ") ;
	}
	feedback(tmp) ;
}


 void sundc(void)
{
#ifdef CALLDEBUG
	calldbg("sundc") ;
#endif
	suntalk("Sundc") ;
	feedback("DISCONNECTED") ;
}

 void sunmd(void)
{
#ifdef CALLDEBUG
	calldbg("sunmd") ;
#endif
	p_scpym(tmp, "Sunmd ", sunname, NULL) ;
	suntalk(tmp) ;
	if (p_mkdir(sunname) != 0)
	{
		feedback("BADMKDIR") ;
	}
	else
	{
		feedback("OK") ;
	}
}

 void sungf (void)
{

#ifdef CALLDEBUG
	calldbg("sungf") ;
#endif
	if (tmode == 1)
	{
		sungfb() ;
	}
	else
	{
		sungfb() ;
	}
}

 void sungfb(void)
{
	INT ret, tctr, dctr, max;
#ifdef CALLDEBUG
	calldbg("sungfb") ;
#endif
	p_scpym(tmp, "Sunfgb ", sunname, NULL) ;
	suntalk(tmp) ;
	feedback("STARTGET") ;
	ret = p_open(&fileh, sunname, P_FSTREAM | P_FUPDATE | P_FCREATE) ; ;
	if ( ret != 0 )
	{
		feedback("BADOPEN") ;
		p_print("p_open returns %d\n", ret) ;
		return ;
	}
	else
	{
		feedback("GOODOPEN") ;
	}
	/* loop, getting the line , decoding it and writting it */
	while (ret == 0)
	{
		ioget() ;
		if (p_scmp("XE", dectxt) == 0)
			break ;
		dctr = 0 ;
		tctr = 0 ;
		max = p_slen(dectxt) ;
		/* decode the line */
		while (dctr < max)
		{
			tmp[tctr] = (((dectxt[dctr] - 'A') * 16) + (dectxt[dctr + 1] - 'A')) ;
			tctr ++ ;
			dctr += 2 ;
		}
		/* we have now assembled the output line, lets write it */
		ret = p_write(fileh, tmp, tctr) ;
	}
	if (ret != 0)
	{
		feedback("BADGET") ;
		ret = p_close(fileh) ;
		return ;
	}
	ret = p_close(fileh) ;
	if (ret != 0)
	{
		feedback("BADGET") ;
		return ;
	}
	
	feedback("ENDGET") ;
}

 void suncs(void)
{
	UWORD sum ;
	TEXT htxt [20] ;
	INT ret ;
#ifdef CALLDEBUG
	calldbg("suncs") ;
#endif
	p_scpym(tmp, "Suncs ", sunname, NULL) ;
	suntalk(tmp) ;
	feedback("STARTSUM") ;
	ret = p_open(&fileh, sunname, P_FOPEN | P_FSTREAM | P_FSHARE) ;
	if ( ret < 0 )
	{
		feedback("BADOPEN") ;
		return ;
	}
	else
	{
		feedback("GOODOPEN") ;
	}
	sum = 0 ;
	ret = 0 ;
	while ( ret >= 0)
	{
		ret = p_read(fileh, dectxt, MAXRD) ;
		if (ret <= 0)
		{
			break ;
		}
		else
		{
			p_crc(&sum, dectxt, ret) ;
		}
	}
	if ((ret != E_FILE_EOF) && ( ret != 0))
	{
		feedback("BADSUM") ;
		p_close(fileh) ;
	}
	htxt[p_ltob(htxt,(ULONG) sum)] = 0 ;
	feedback(htxt) ;
	feedback("ENDSUM") ;
	p_close(fileh) ;
}


 void sunpf(void)
{
	INT ret, hctr, dctr ;
#ifdef CALLDEBUG
	calldbg("sunpf") ;
#endif
	p_scpym(tmp, "Sunpf ", sunname, NULL) ;
	suntalk(tmp) ;
	feedback("STARTPUT") ;
	ret = p_open(&fileh, sunname, P_FOPEN | P_FSTREAM | P_FSHARE) ;
	if ( ret < 0 )
	{
		feedback("BADOPEN") ;
		return ;
	}
	else
	{
		feedback("GOODOPEN") ;
	}
	ret = 0 ;
	while ( ret >= 0)
	{
		ret = p_read(fileh, dectxt, MAXRD) ;
		if (ret <= 0)
		{
			break ;
		}
		hctr = dctr = 0 ;
		/* process the string to convert to HEX from ASCII */
		while (dctr < ret)
		{
			/* convert the ascii to hex */
			/* use a bit mask and index array, p_gtob doesn't seem
			   to be able to handle it properley */
			hextxt[hctr++] = hexarr[(dectxt[dctr] & 0x00F0) >> 4] ;
			hextxt[hctr++] = hexarr[dectxt[dctr++] & 0x000F] ;
		}
		/* terminate the string */
		hextxt[hctr] = '\0' ;
		putline(hextxt, 1) ;
		
	}
	feedback("E") ;
	if ((ret != E_FILE_EOF) && ( ret != 0))
	{
		feedback("BADPUT") ;
		p_close(fileh) ;
	}
	feedback("ENDPUT") ;
	p_close(fileh) ;
}

 void sunsl(void)
{
#ifdef CALLDEBUG
	calldbg("sunsl") ;
#endif
	suntalk("Sunsl") ;
	sndline = 0 ;
	feedback("OK") ;
	wsnd() ;
}

 void sunrl(void)
{
#ifdef CALLDEBUG
	calldbg("sunrl") ;
#endif
	suntalk("Sunrl") ;
	lineid = 0 ;
	feedback("OK") ;
	wline() ;
}

 void initscr(void)
{
	
#ifdef CALLDEBUG
	calldbg("initscr") ;
#endif
	/* paths window */
	wdpath.extent.tl.x = 0 ;
	wdpath.extent.tl.y = 60 ;
	wdpath.extent.width = 235 ;
	wdpath.extent.height = 15 ;
	wdpath.flags = W_WIN_PRIORITY ;
	wdpath.mouse_icon = 0 ;
	wdpath.filler = 0;
	wdpath.background = W_WIN_BACK_BITMAP ;
	/* the toggles window */
	wdtog.extent.tl.x = 120 ;
	wdtog.extent.tl.y = 0 ;
	wdtog.extent.width = 115 ;
	wdtog.extent.height = 35 ;
	wdtog.flags = W_WIN_PRIORITY ;
	wdtog.mouse_icon = 0 ;
	wdtog.filler = 0;
	wdtog.background = W_WIN_BACK_BITMAP ;
	/* the message window */
	wdtalk.extent.tl.x = 0 ;
	wdtalk.extent.tl.y = 40 ;
	wdtalk.extent.width = 235 ;
	wdtalk.extent.height = 15 ;
	wdtalk.flags = W_WIN_PRIORITY ;
	wdtalk.mouse_icon = 0 ;
	wdtalk.filler = 0;
	wdtalk.background = W_WIN_BACK_BITMAP ;
	/* the recieved line window */
	wdline.extent.tl.x = 0 ;
	wdline.extent.tl.y = 0 ;
	wdline.extent.width = 115 ;
	wdline.extent.height = 15 ;
	wdline.flags = W_WIN_PRIORITY ;
	wdline.mouse_icon = 0 ;
	wdline.filler = 0;
	wdline.background = W_WIN_BACK_BITMAP ;
	/* the sent line window */
	wdsnd.extent.tl.x = 0 ;
	wdsnd.extent.tl.y = 20 ;
	wdsnd.extent.width = 115 ;
	wdsnd.extent.height = 15 ;
	wdsnd.flags = W_WIN_PRIORITY ;
	wdsnd.mouse_icon = 0 ;
	wdsnd.filler = 0;
	wdsnd.background = W_WIN_BACK_BITMAP ;
	/* setup the gc data structs (all the same realy ) */
	gdline.gmode = G_TRMODE_SET ;
	gdline.textmode = G_TRMODE_REPL ;
	gdline.style = G_STY_NORMAL ;
	gdline.filler = 0 ;
	gdline.font = WS_FONT_BASE ;
	gdsnd.gmode = G_TRMODE_SET ;
	gdsnd.textmode = G_TRMODE_REPL ;
	gdsnd.style = G_STY_NORMAL ;
	gdsnd.filler = 0 ;
	gdsnd.font = WS_FONT_BASE ;
	gdtog.gmode = G_TRMODE_SET ;
	gdtog.textmode = G_TRMODE_REPL ;
	gdtog.style = G_STY_NORMAL ;
	gdtog.filler = 0 ;
	gdtog.font = WS_FONT_BASE ;
	gdpath.gmode = G_TRMODE_SET ;
	gdpath.textmode = G_TRMODE_REPL ;
	gdpath.style = G_STY_NORMAL ;
	gdpath.filler = 0 ;
	gdpath.font = WS_FONT_BASE ;
	gdtalk.gmode = G_TRMODE_SET ;
	gdtalk.textmode = G_TRMODE_REPL ;
	gdtalk.style = G_STY_NORMAL ;
	gdtalk.filler = 0 ;
	gdtalk.font = WS_FONT_BASE ;
	/* actualy create the sub windows */
	/* the path data window */
	winpath= wCreateWindow(0, W_WIN_EXTENT | W_WIN_BACKGROUND , &wdpath, 1) ;
	wInitialiseWindowTree(winpath) ;
	gcpath= gCreateGC(winpath, G_GC_MASK_GMODE | G_GC_MASK_TEXTMODE | G_GC_MASK_STYLE, &gdpath) ;
	wMakeVisible(winpath) ;
	gSetGC0(gcpath) ;
	gBorder(W_BORD_CUSHION|W_BORD_SHADOW_S|W_BORD_SHADOW_ON) ;
	wpath() ;
	/* the  togles window */
	wintog= wCreateWindow(0, W_WIN_EXTENT | W_WIN_BACKGROUND , &wdtog, 2) ;
	wInitialiseWindowTree(wintog) ;
	gctog= gCreateGC(wintog, G_GC_MASK_GMODE | G_GC_MASK_TEXTMODE | G_GC_MASK_STYLE, &gdtog) ;
	wMakeVisible(wintog) ;
	gSetGC0(gctog) ;
	gBorder(W_BORD_CUSHION|W_BORD_SHADOW_S|W_BORD_SHADOW_ON) ;
	wvb() ;
	wtm() ;
	wsc() ;
	/* the message window */
	wintalk= wCreateWindow(0, W_WIN_EXTENT | W_WIN_BACKGROUND , &wdtalk, 3) ;
	wInitialiseWindowTree(wintalk) ;
	gctalk= gCreateGC(wintalk, G_GC_MASK_GMODE | G_GC_MASK_TEXTMODE | G_GC_MASK_STYLE, &gdtalk) ;
	wMakeVisible(wintalk) ;
	gSetGC0(gctalk) ;
	gBorder(W_BORD_CUSHION|W_BORD_SHADOW_S|W_BORD_SHADOW_ON) ;
	wtalk("") ;
	/* the recieved line count */
	winline= wCreateWindow(0, W_WIN_EXTENT | W_WIN_BACKGROUND , &wdline, 4) ;
	wInitialiseWindowTree(winline) ;
	gcline= gCreateGC(winline, G_GC_MASK_GMODE | G_GC_MASK_TEXTMODE | G_GC_MASK_STYLE, &gdline) ;
	wMakeVisible(winline) ;
	gSetGC0(gcline) ;
	gBorder(W_BORD_CUSHION|W_BORD_SHADOW_S|W_BORD_SHADOW_ON) ;
	wsline() ;
	wline() ;
	/* the sent line count */
	winsnd= wCreateWindow(0, W_WIN_EXTENT | W_WIN_BACKGROUND , &wdsnd, 5) ;
	wInitialiseWindowTree(winsnd) ;
	gcsnd= gCreateGC(winsnd, G_GC_MASK_GMODE | G_GC_MASK_TEXTMODE | G_GC_MASK_STYLE, &gdsnd) ;
	wMakeVisible(winsnd) ;
	gSetGC0(gcsnd) ;
	gBorder(W_BORD_CUSHION|W_BORD_SHADOW_S|W_BORD_SHADOW_ON) ;
	wssnd() ;
	wsnd() ;
	/* ensure that any screen message is nolonger displayed */
	wCancelBusyMsg() ;
}

 void sunol(void)
{
#ifdef CALLDEBUG
	calldbg("sunol") ;
#endif
	feedback("ONLINE") ;
}

 void shutdown(void)
{
#ifdef CALLDEBUG
	calldbg("shutdown") ;
#endif
	p_close(devh) ;
	/* I think that we should destroy the graphics contexts and windows  */
	wFree(gcline) ;
	wFree(gcsnd) ;
	wFree(gcpath) ;
	wFree(gctog) ;
	wFree(gctalk) ;
	wDisconnect() ;
}

 void wpath(void)
{
#ifdef CALLDEBUG
	calldbg("wpart") ;
#endif
	if (scr != 1)
		return ;
	gSetGC0(gcpath) ;
	p_scpym(wtmp, "Path : ", sunname, spacestr, NULL) ;
	gPrintClipText(5, 10, wtmp, p_slen(wtmp), FULLWIDTH) ;
}

 void wvb(void)
{
#ifdef CALLDEBUG
	calldbg("wvb") ;
#endif
	if (scr != 1)
		return ;
	gSetGC0(gctog) ;
	if (vrb)
		p_scpym(wtmp, "Verbose : YES", spacestr, NULL) ;
	else
		p_scpym(wtmp, "Verbose : NO  ", spacestr, NULL) ;
	gPrintClipText(5 ,10, wtmp, p_slen(wtmp),HALFWIDTH) ;
}

 void wtm(void)
{
#ifdef CALLDEBUG
	calldbg("wtm") ;
#endif
	if (scr != 1)
		return ;
	if (tmode == 1)
		p_scpym(wtmp, "Transfer : ASCII", spacestr, NULL) ;
	else
		p_scpym(wtmp, "Transfer : BINARY ", spacestr, NULL) ;
	gSetGC0(gctog) ;
	gPrintClipText(5, 20, wtmp, p_slen(wtmp), HALFWIDTH) ;
}

 void wsc(void)
{
#ifdef CALLDEBUG
	calldbg("wsc") ;
#endif
	gSetGC0(gctog) ;
	if (scr == 0)
		p_scpym(wtmp, "Screen Update NO", spacestr, NULL) ;
	else
		p_scpym(wtmp, "Screen Update YES", spacestr, NULL) ;
	gPrintClipText(5, 30, wtmp, p_slen(wtmp) , HALFWIDTH) ;
}

 void wtalk( TEXT * msg)
{
#ifdef CALLDEBUG
	calldbg("wtalk") ;
#endif
	if (scr != 1)
		return ;
	gSetGC0(gctalk) ;
	wtmp[0] = '\0' ;
	p_scpym(wtmp, msg, spacestr, NULL) ;
	gPrintClipText(5,10,wtmp, p_slen(wtmp), FULLWIDTH ) ;
}

 void wsline(void)
{
#ifdef CALLDEBUG
	calldbg("wsline") ;
#endif
	gSetGC0(gcline) ;
	p_scpy(wtmp, "Recieved Ctr :");
	gPrintText(5, 10, wtmp, p_slen(wtmp)) ;
	lineidpt = gTextWidth(WS_FONT_BASE, G_STY_NORMAL, wtmp, p_slen(wtmp)) ;
}

 void wssnd(void)
{
#ifdef CALLDEBUG
	calldbg("wssnd") ;
#endif
	gSetGC0(gcsnd) ;
	p_scpy(wtmp, "Sent Ctr : ");
	gPrintText(5,10,wtmp, p_slen(wtmp)) ;
	sndlinept = gTextWidth(WS_FONT_BASE, G_STY_NORMAL, wtmp, p_slen(wtmp)) ;
}

 void wline(void)
{
	TEXT linet[10] ;
#ifdef CALLDEBUG
	calldbg("wline") ;
#endif
	if (scr != 1) 
		return ;
	gSetGC0(gcline) ;
	linet[p_itob(linet, lineid)] = '\0' ;
	p_scpym(wtmp, linet, spacestr, NULL) ;
	gPrintClipText(lineidpt, 10, wtmp, p_slen(wtmp), HALFWIDTH - lineidpt) ;
	
}

 void wsnd(void)
{
	TEXT linet[10] ;
#ifdef CALLDEBUG
	calldbg("wsnd") ;
#endif
	if (scr != 1)
		return ;
	gSetGC0(gcsnd) ;
	linet[p_itob(linet, sndline)] = '\0' ;
	p_scpym(wtmp, linet, "  ", NULL) ;
	gPrintClipText(sndlinept, 10, wtmp, p_slen(wtmp), HALFWIDTH - sndlinept) ;
}

 void suntalk(TEXT *msg)
{
	
	if (scr != 1)
		return ;
	wtalk(msg) ;
}
