[comp.sources.atari.st] v01i045: zmdm -- terminal program with file transfer part05/08

koreth@ssyx.ucsc.edu (Steven Grimm) (05/30/88)

Submitted-by: bammi@mandrill.ces.cwru.edu (Jwahar R. Bammi)
Posting-number: Volume 1, Issue 45
Archive-name: zmdm/part05

#!/bin/sh
# this is part 5 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file SZ.C continued
#
CurArch=5
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file SZ.C"
sed 's/^X//' << 'SHAR_EOF' >> SZ.C
X		fflush(logf);
X
X	}
X#endif
X	stalarm(c);
X	c=read_modem(byt, count);
X
X	stalarm(0);
X#ifdef SDEBUG
X	if (Verbose>5)
X	{
X		fprintf(STDERR, "ret cnt=%d %x %x\n", c, byt[0], byt[1]);
X		fprintf(logf, "ret cnt=%d %x %x\n", c, byt[0], byt[1]);
X		fflush(logf);
X	}
X#endif
X
X	if (c<1)
X		return TIMEOUT;
X	if (c==1)
X		return (byt[0]&0377);
X	else
X		while (c)
X			if (byt[--c] != CAN)
X				return ERROR;
X	return CAN;
X}
X
Xsreadline(n)
X{
X	return (readock(n, 1));
X}
X
X
Xsusage()
X{
X	fprintf(STDERR,"\nSend file(s) with ZMODEM/YMODEM/XMODEM Protocol\n");
X	fprintf(STDERR,"	(Y) = Option applies to YMODEM only\n");
X	fprintf(STDERR,"	(Z) = Option applies to ZMODEM only\n");
X	fprintf(STDERR,
X	"%s for %s by ST Enthusiasts at Case Western Reserve University\n",
X	   SSTVERSION, STOS);
X	fprintf(STDERR,"\tBased on %s for %s by Chuck Forsberg\n\n", SVERSION, OS);
X/*	fprintf(STDERR,"Usage:	sz [-12+adefknquvXy] [-] file ...\n"); */
X	fprintf(STDERR,"Usage:	sz [-+defknquvXyB] file ...\n");
X/*	fprintf(STDERR,"	sz [-1eqv] -c COMMAND\n"); */
X	fprintf(STDERR,"	sz [-eqv] -c COMMAND\n");
X/*	fprintf(STDERR,"	1 Use stdout for modem input\n"); */
X#ifdef CSTOPB
X	fprintf(STDERR,"	2 Use 2 stop bits\n");
X#endif
X	fprintf(STDERR,"	+ Append to existing destination file (Z)\n");
X/*	fprintf(STDERR,"	a (ASCII) change NL to CR/LF\n"); */
X	fprintf(STDERR,"	c send COMMAND (Z)\n");
X	fprintf(STDERR,"	d Change '.' to '/' in pathnames (Y/Z)\n");
X	fprintf(STDERR,"	e Escape control characters (Z)\n");
X	fprintf(STDERR,"	f send Full pathname (Y/Z)\n");
X	fprintf(STDERR,"	i send COMMAND, ack Immediately (Z)\n");
X	fprintf(STDERR,"	k Send 1024 byte packets (Y)\n");
X	fprintf(STDERR,"	L N Limit packet length to N bytes (Z)\n");
X	fprintf(STDERR,"	l N Limit frame length to N bytes (l>=L) (Z)\n");
X	fprintf(STDERR,"	n send file if Newer|longer (Z)\n");
X	fprintf(STDERR,"	N send file if different length|date (Z)\n");
X	fprintf(STDERR, "	o Use 16 bit CRC instead of 32 bit CRC (Z)\n");
X	fprintf(STDERR,"	p Protect existing destination file (Z)\n");
X	fprintf(STDERR,"	r Resume/Recover interrupted file transfer (Z)\n");
X	fprintf(STDERR,"	q Quiet (no progress reports)\n");
X	fprintf(STDERR,"	u Unlink file after transmission\n");
X	fprintf(STDERR,"	v Verbose - debugging information\n");
X	fprintf(STDERR,"	X XMODEM protocol - send no pathnames\n");
X	fprintf(STDERR,"	y Yes, overwrite existing file (Z)\n");
X	fprintf(STDERR,"	B Force Binary mode transfers (Z)\n");
X/*	fprintf(STDERR,
X"- as pathname sends standard input as sPID.sz or environment ONAME\n"); */
X	return(1);
X}
X
X/*
X * Get the receiver's init parameters
X */
Xgetzrxinit()
X{
X	register int n;
X
X	for (n=10; --n>=0; ) {
X		
X		switch (zgethdr(Rxhdr, 1)) {
X		case ZCHALLENGE:	/* Echo receiver's challenge numbr */
X			stohdr(Rxpos);
X			zshhdr(ZACK, Txhdr);
X			continue;
X		case ZCOMMAND:		/* They didn't see out ZRQINIT */
X			stohdr(0L);
X			zshhdr(ZRQINIT, Txhdr);
X			continue;
X		case ZRINIT:
X			Rxflags = 0377 & Rxhdr[ZF0];
X 			Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
X
X			Rxbuflen = (0337 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
X			vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen);
X			siggi = 0;
X#ifndef READCHECK
X#ifdef USG
X			mode(2);	/* Set cbreak, XON/XOFF, etc. */
X#else
X			/* Use 1024 byte frames if no sample/interrupt */
X			if (Rxbuflen < 32 || Rxbuflen > 1024) {
X				Rxbuflen = 1024;
X				vfile("Rxbuflen=%d", Rxbuflen);
X			}
X#endif
X#endif
X			/* Override to force shorter frame length */
X			if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))
X				Rxbuflen = Tframlen;
X			if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))
X				Rxbuflen = Tframlen;
X			vfile("Rxbuflen=%d", Rxbuflen);
X
X			/*
X			 * If input is not a regular file, force ACK's each 1024
X			 *  (A smarter strategey could be used here ...)
X			 */
X			if ((Rxbuflen == 0) || (Rxbuflen > 1024))
X				Rxbuflen = 1024;
X			vfile("Rxbuflen=%d", Rxbuflen);
X
X			return (sendzsinit());
X		case ZCAN:
X		case TIMEOUT:
X			return ERROR;
X		case ZRQINIT:
X			if (Rxhdr[ZF0] == ZCOMMAND)
X				continue;
X		default:
X			zshhdr(ZNAK, Txhdr);
X			continue;
X		}
X	}
X	return ERROR;
X}
X
X/* Send send-init information */
Xsendzsinit()
X{
X	register int c;
X	register int errors;
X
X	if (Myattn[0] == '\0')
X		return OK;
X
X	errors = 0;
X	for (;;) {
X		stohdr(0L);
X		zsbhdr(ZSINIT, Txhdr);
X		zsdata(Myattn, 1+strlen(Myattn), ZCRCW);
X		c = zgethdr(Rxhdr, 1);
X		switch (c) {
X		case ZCAN:
X			return ERROR;
X		case ZACK:
X			return OK;
X		default:
X			if (++errors > 9)
X				return ERROR;
X			continue;
X		}
X	}
X}
X
X/* Send file name and related info */
Xzsendfile(buf, blen, szbytes)
Xchar *buf;
Xint blen;
Xlong szbytes;
X{
X	register int c, szstat;
X	long start_time, end_time;
X	extern void rd_time();
X
X	Supexec(rd_time);
X	start_time = pr_time;
X	
X	for (;;) {
X		Txhdr[ZF0] = Lzconv;	/* file conversion request */
X		Txhdr[ZF1] = Lzmanag;	/* file management request */
X		Txhdr[ZF2] = Lztrans;	/* file transport request */
X		Txhdr[ZF3] = 0;
X		zsbhdr(ZFILE, Txhdr);
X		zsdata(buf, blen, ZCRCW);
Xagain:
X		c = zgethdr(Rxhdr, 1);
X		switch (c) {
X		case ZRINIT:
X			goto again;
X		case ZCAN:
X		case TIMEOUT:
X		case ZABORT:
X		case ZFIN:
X			return ERROR;
X		case ZSKIP:
X#ifndef REMOTE
X			fprintf(STDERR,"\n\n");
X#endif
X			stfclose(in); in = (-1); return c;
X		case ZRPOS:
X			if(stfseek(in, Rxpos, 0))
X			{
X				fprintf(STDERR,"\r\nError While Seeking file\n");
X				return ERROR;
X			}
X			Txpos = Rxpos; Lastc = (-1); Dontread = FALSE;
X			if((szstat =  zsendfdata()) == OK)
X			{
X#ifndef REMOTE
X				Supexec(rd_time);
X				end_time = pr_time;
X				fprintf(STDERR,"%ld Bytes Sent\t\
XTransfer Time %ld secs.\tApprox %ld cps\n\n", szbytes, (end_time - start_time)/200L,
Xszbytes/((end_time - start_time)/200L));
X#endif
X			}
X			return szstat;
X		case ERROR:
X		default:
X			continue;
X		}
X	}
X}
X
X/* Send the data in the file */
Xzsendfdata()
X{
X	register int c, c1, e;
X	register int newcnt;
X	register long tcount = 0;
X	static int tleft = 6;	/* Counter for test mode */
X	
X	if (Baudrate > 300)
X		Blklen = 256;
X	if (Baudrate > 2400)
X		Blklen = KSIZE;
X/*	if (Rxbuflen && Blklen>Rxbuflen)  --jrb do not limit block size */
X	if (Rxbuflen)
X		Blklen = Rxbuflen;
X	if (blkopt && Blklen > blkopt)
X		Blklen = blkopt;
X	vfile("Rxbuflen=%d Blklen=%d", Rxbuflen, Blklen);
Xsomemore:
X	if (setjmp(intrjmp)) {
Xwaitack:
X		switch (c1 = getinsync()) {
X		default:
X		case ZCAN:
X			fprintf(STDERR,"\r\nReceiver Cancelled Transfer\n\n");
X			stfclose(in);
X			in = (-1);
X			return ERROR;
X		case ZSKIP:
X#ifndef REMOTE
X			fprintf(STDERR,"\r\nReceiver forced SKIP Transfer(1)\n\n");
X#endif
X			stfclose(in);
X			in = (-1);
X			return c1;
X		case ZACK:
X			tcount += c;
X			lreport(tcount);
X			/* fall thru */
X		case ZRPOS:
X			break;
X		case ZRINIT:
X			return OK;
X		}
X	}
X
X	siggi = 1;
X	newcnt = Rxbuflen;
X	stohdr(Txpos);
X	zsbhdr(ZDATA, Txhdr);
X
X	/*
X	 * Special testing mode.  This should force receiver to Attn,ZRPOS
X	 *  many times.  Each time the signal should be caught, causing the
X	 *  file to be started over from the beginning.
X	 */
X#ifdef TESTATTN
X	if (Testattn) {
X		if ( --tleft)
X			while (tcount < 20000) {
X				wr_modem(qbf);
X				tcount += strlen(qbf);
X#ifdef READCHECK
X				while (Bconstat(1)) {
X					switch (sreadline(1)) {
X					case CAN:
X					case ZPAD:
X						goto waitack;
X					}
X				}
X#endif
X			}
X		siggi = 0; canit();
X		stsleep(3); purgeline(); mode(0);
X#ifdef SDEBUG
X		if(logf != (FILE *)NULL)
X			fclose(logf);
X#endif
X
X/*		printf("\nsz: Tcount = %ld\n", tcount); */
X		if (tleft) {
X			/* printf("\r\nERROR: Interrupts Not Caught\n"); */
X			aexit(1);
X		}
X		aexit(0);
X	}
X#endif
X
X	do {
X		if (Dontread) {
X			c = Lastc;
X		} else {
X			c = zfilbuf(secbuf, Blklen);
X			Lastread = Txpos;  Lastc = c;
X		}
X#ifdef SDEBUG
X		if (Verbose > 10)
X			vfile("Dontread=%d c=%d", Dontread, c);
X#endif
X
X		Dontread = FALSE;
X		if (c < Blklen)
X			e = ZCRCE;
X		else if (Rxbuflen && (newcnt -= c) <= 0)
X			e = ZCRCW;
X		else
X			e = ZCRCG;
X		zsdata(secbuf, c, e);
X		Txpos += c;
X		if(e == ZCRCG)
X		{
X			tcount += c;
X			lreport(tcount);
X		}
X
X		if (e == ZCRCW)
X			goto waitack;
X#ifdef READCHECK
X		/*
X		 * If the reverse channel can be tested for data,
X		 *  this logic may be used to detect error packets
X		 *  sent by the receiver, in place of setjmp/longjmp
X		 *  rdchk(fdes) returns non 0 if a character is available
X		 */
X		flush_modem();
X		while (Bconstat(1)) {
X			switch (sreadline(1)) {
X			case CAN:
X			case ZPAD:
X				zsdata(secbuf, 0, ZCRCE);
X				goto waitack;
X			}
X		}
X#endif
X	} while (c == Blklen);
X	tcount += c;
X	lreport(tcount);
X	siggi = 0;
X	lsct = 1;
X
X	for (;;) {
X		stohdr(Txpos);
X		zsbhdr(ZEOF, Txhdr);
X		switch (getinsync()) {
X		case ZACK:
X			continue;
X		case ZRPOS:
X			goto somemore;
X		case ZRINIT:
X			return OK;
X		case ZSKIP:
X#ifndef REMOTE
X			fprintf(STDERR,"\r\nReceiver forced SKIP Transfer(2)\n\n");
X#endif
X			stfclose(in);
X			in = (-1);
X			return c;
X		default:
X			fprintf(STDERR,"\r\nErrors while Send Data\n\n");
X			stfclose(in);
X			in = (-1);
X			return ERROR;
X		}
X	}
X}
X
X/*
X * Respond to receiver's complaint, get back in sync with receiver
X */
Xgetinsync()
X{
X	register int c;
X
X	for (;;) {
X#ifdef TESTATTN
X		if (Testattn) {
X			wr_modem("\r\n\n\n***** Signal Caught *****\r\n");
X			Rxpos = 0; c = ZRPOS;
X		} else
X#endif
X
X			c = zgethdr(Rxhdr, 0);
X		switch (c) {
X		case ZCAN:
X		case ZABORT:
X		case ZFIN:
X		case TIMEOUT:
X			return ERROR;
X		case ZRPOS:
X			if (Lastc >= 0 && Lastread == Rxpos) {
X				Dontread = TRUE;
X			} else {
X				/* clearerr(in); */	/* In case file EOF seen */
X				if(stfseek(in, Rxpos, 0))
X				{
X					fprintf(STDERR,"\r\nError While Seeking file\n");
X					return ERROR;
X				}
X
X			}
X			Txpos = Rxpos;
X			return c;
X		case ZACK:
X			return c;
X		case ZRINIT:
X		case ZSKIP:
X#ifndef REMOTE
X			fprintf(STDERR,"\n\n");
X#endif
X			stfclose(in);
X			in = (-1);
X			return c;
X		case ERROR:
X		default:
X			zsbhdr(ZNAK, Txhdr);
X			continue;
X		}
X	}
X}
X/* Say "bibi" to the receiver, try to do it cleanly */
Xsaybibi()
X{
X	for (;;) {
X		stohdr(0L);
X		zsbhdr(ZFIN, Txhdr);
X		switch (zgethdr(Rxhdr, 0)) {
X		case ZFIN:
X			sendline('O'); sendline('O'); flush_modem();
X		case ZCAN:
X		case TIMEOUT:
X			return;
X		}
X	}
X}
X
X/* Send command and related info */
Xzsendcmd(buf, blen)
Xchar *buf;
X{
X	register int c, errors;
X	long cmdnum;
X
X/*	cmdnum = getpid(); */
X	cmdnum = 1;	/* A random # */
X	errors = 0;
X	for (;;) {
X		stohdr(cmdnum);
X		Txhdr[ZF0] = Cmdack1;
X		zsbhdr(ZCOMMAND, Txhdr);
X		zsdata(buf, blen, ZCRCW);
Xlisten:
X		Rxtimeout = 100;		/* Ten second wait for resp. */
X		c = zgethdr(Rxhdr, 1);
X
X		switch (c) {
X		case ZRINIT:
X			continue;
X		case ERROR:
X		case TIMEOUT:
X			if (++errors > Cmdtries)
X				return ERROR;
X			continue;
X		case ZCAN:
X		case ZABORT:
X		case ZFIN:
X		case ZSKIP:
X		case ZRPOS:
X			return ERROR;
X		default:
X			if (++errors > 10)
X				return ERROR;
X			continue;
X		case ZCOMPL:
X			Exitcode = Rxpos;
X			saybibi();
X			return OK;
X		case ZRQINIT:
X			vfile("******** RZ *******");
X/*			stsystem("rz"); */
X			vfile("******** SZ *******");
X			goto listen;
X		}
X	}
X}
X
X
X#ifndef STANDALONE
X/*
X * If called as sb use YMODEM protocol
X */
Xschkinvok(s)
Xchar *s;
X{
X	if (s[0]=='s' && s[1]=='b') {
X		Nozmodem = TRUE; Blklen=KSIZE;
X	}
X}
X#endif
X
X/* -eof- */
SHAR_EOF
echo "File SZ.C is complete"
chmod 0600 SZ.C || echo "restore of SZ.C fails"
echo "x - extracting SZLNK (Text)"
sed 's/^X//' << 'SHAR_EOF' > SZLNK &&
Xc:\lib\gemstart.o common.o sz.o util.o tyme.o zm.o fileio.o
Xc:\lib\osbind.o c:\lib\gemlib c:\lib\libf
SHAR_EOF
chmod 0600 SZLNK || echo "restore of SZLNK fails"
echo "x - extracting TRANSFER.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > TRANSFER.C &&
X/*
X * 	(Quick & Dirty) Transfer Shell
X *
X *		Jwahar Bammi
X *			usenet: mandrill!bammi@{decvax,sun}.UUCP
X *			csnet:  bammi@mandrill.ces.CWRU.edu
X *			arpa:   bammi@mandrill.ces.CWRU.edu
X *			CompuServe: 71515,155
X */
X
X#include "config.h"
X
X#ifdef DLIBS
X#include <string.h>
X#endif
X
X#include "zmdm.h"
X#include "common.h"
X
X#define ISWILD(X)	((X == '*')||(X == '?'))
X#define PROMPT		fprintf(STDERR,"zmdm> ")
X
Xextern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
X	   hhelp();
X
X#ifdef RECURSE
Xextern int doszf();
X#endif
X
Xstatic struct comnds {
X	char	*command;	/* command string	*/
X	int     (*routine)();	/* routine to invoke	*/
X	char	*synopsis;	/* synopsis		*/
X	int	expand;		/* expand wildcards before calling routine? */
X} comtab [] = {
X	{ "rz",	dorz, "receive files using Z/X modem protocol",       TRUE },
X	{ "rb", dorz, "receive files using Y modem protocol",         TRUE },
X#ifdef RECURSE
X	{ "sz", doszf, "send files using Z/Y/X modem protocol",        TRUE },
X#else
X	{ "sz", dosz, "send files using Z/Y/X modem protocol",        TRUE },
X#endif
X	{ "sb", dosz, "send files using Y modem protocol",            TRUE },
X	{ "rm", rm,   "remove files",                                 TRUE },
X	{ "cp", cp,   "copy files",                                   TRUE },
X	{ "ls", ls,   "list directory",                               FALSE},
X	{ "cd", cd,   "change working directory",			 FALSE},
X	{ "md", md,   "make a directory",				 FALSE},
X	{ "rd", rd,   "remove a directory",			         FALSE},
X	{ "pwd",pwd,  "print  working directory",			 FALSE},
X	{ "df", df,   "check free space",				 FALSE},
X	{ "?",  hhelp, "this message",					 FALSE},
X	{ (char *)NULL, (int (*)())NULL, (char *)NULL,                   FALSE}
X};
X
X#define MAXARGS	1024
Xstatic char *targv[MAXARGS];
Xstatic int targc;
Xchar *alltolower();
X
Xtransfer()
X{
X	char linebuf[132];
X	char *line;
X	int command;
X	int status;
X	extern int find_command();
X	extern int expnd_args();
X#ifdef DEBUG
X	int i;
X#endif
X
X	fprintf(STDERR,"hit <RETURN> to return to emulator,  <?> for help\n\n");
X	targc = 0;
X	while (TRUE)
X	{
X		if(targc > 1)
X			free_args();
X
X		PROMPT;
X		linebuf[0] = 127;
X#ifndef REMOTE
X		Cconrs(linebuf);
X#else
X		Cconraux(linebuf);
X#endif
X		putc('\n', STDERR);
X		if(linebuf[1] == 0)
X		/* cancelled */
X		return;
X		
X		linebuf[(linebuf[1]+2)] = '\0';
X		line = &linebuf[2];
X#ifdef DEBUG
Xprintf("Line: |%s|\n", line);
X#endif
X
X		targv[0] = line;
X		targc    = 1;
X	
X		/* pick up targv[0] */
X		while((*line != '\0') && (!isspace(*line)))
X			line++;
X
X		if(*line != '\0')
X		{
X			*line++ = '\0';
X		}
X
X		if((command = find_command(targv[0])) < 0)
X		{
X			fprintf(STDERR,"Invalid Command\n");
X			continue;
X		}
X
X		if(expnd_args(line, comtab[command].expand))
X			/* too many args */
X			continue;
X#ifdef DEBUG
Xprintf("targc %d\n", targc);
Xfor(i = 0; i < targc; i++)
X	printf("%s ", targv[i]);
Xprintf("\n\n");
X#endif
X
X		if((status = (*(comtab[command].routine))(targc, targv)) != 0)
X			fprintf(STDERR,"Exit Status %d\n", status);
X
X#ifdef DEBUG
Xprintf("Exit Status %d\n", status);
X#endif
X
X	} /* While */
X}
X
X/*
X * Straight sequential search thru comtab
X */		
Xint find_command(s)
Xregister char *s;
X{
X	register int i;
X
X	for(i = 0; comtab[i].command != (char *)NULL; i++)
X	{
X		if(strcmp(s, comtab[i].command) == 0)
X			return i;
X	}
X
X	return -1;
X}
X
X/*
X * Expand command line args, return TRUE if too many args, or Not matching Quotes
X */
Xint expnd_args(s, expand_wild)
Xregister char *s;
Xint expand_wild;
X{
X	char next_arg[128];
X	register char *p;
X	register int contains_wild;
X	extern int add_argv();
X	extern int handl_wild();
X
X	while(*s != '\0')
X	{
X		p = next_arg;
X		while(isspace(*s)) s++; /* skip leading space */
X		if(*s != '\0')
X		{
X			contains_wild = FALSE;
X			if(*s == '\047')
X			{
X				/* Quoted arg */
X				s++;
X				while((*s != '\0') && (*s != '\047'))
X					*p++ = *s++;
X				*p = '\0';
X				if(*s == '\0')
X				{
X					fprintf(STDERR,"No Matching Quote\n");
X					return TRUE;
X				}
X				else
X					s++;
X				if(add_argv(next_arg))
X					return TRUE;
X			}
X			else
X			{
X				while(!isspace(*s) && (*s != '\0'))
X				{
X					contains_wild |= ISWILD(*s);
X					*p++ = *s++;
X				}
X				*p = '\0';
X
X				if(contains_wild && expand_wild)
X				{
X					if(handl_wild(next_arg))
X						return TRUE;
X				}
X				else
X				{
X					if(add_argv(next_arg))
X						return TRUE;
X				}
X			} /* if-else */
X		} /* If */
X	} /* while */
X
X	return FALSE;
X}
X
X/*
X * add an arg to argv. Return TRUE if error
X */
Xint add_argv(s)
Xchar *s;
X{
X	extern char *myalloc();
X	extern char *strcpy();
X	extern int strlen();
X
X	if(targc > (MAXARGS-1))
X	{
X		fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
X		return TRUE;
X	}
X	targv[targc++] = strcpy(myalloc(strlen(s)+1), s);
X	
X	return FALSE;
X	
X}
X
X/*
X * expand wild card arguments. Return TRUE on error.
X */
Xint handl_wild(s)
Xchar *s;
X{
X	extern struct stat statbuf;
X	extern char *mkpathname();
X	
X	if(Fsfirst(s, 0x21) != 0)
X	{
X		/* No match */
X		fprintf(STDERR,"No Match for %s\n", s);
X		return TRUE;
X	}
X
X	alltolower(statbuf.st_name);
X	if(add_argv(mkpathname(s, statbuf.st_name)))
X		return TRUE;
X
X	while(Fsnext() == 0)
X	{
X		alltolower(statbuf.st_name);
X		if(add_argv(mkpathname(s, statbuf.st_name)))
X			return TRUE;
X	}
X
X	return FALSE;
X}
X
X/*
X * Given a spec with a trailing wildcard and a base will name construct pathname
X *
X */
Xchar *mkpathname(spec, file)
Xregister char *spec, *file;
X{
X	extern char *rindex();
X	register char *p;
X
X	if((p = rindex(spec, '\\')) == (char *)NULL)
X		/* no path name */
X		return file;
X
X	while(*file != '\0')
X		*++p = *file++;
X	*++p = '\0';
X	
X	return spec;
X}
X
Xfree_args()
X{
X	register int i;
X	
X	for(i = 1; i < targc; i++)
X		free(targv[i]);
X}
X
X/*
X * remove files
X *	Usage: rm [-i] files ... 
X */	
Xint rm(argc, argv)
Xregister int argc;
Xregister char **argv;
X{
X	register int interactive;
X	register int status, s;
X	extern int yesno();
X	extern int errno;
X
X	interactive = FALSE;
X	status = 0;
X	while(--argc)
X	{
X		++argv;
X		if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
X			interactive = TRUE;
X		else
X		{
X			if(interactive)
X				if(!yesno("rm: remove", *argv))
X					continue;
X			if(unlink(*argv))
X			{
X				s |= 1;
X				fprintf(STDERR, "%s: no such file\n", *argv);
X			}
X			status |= s;
X		}
X	}
X	return status;
X}
X
X/*
X * Prompt and return Yes/No truth value
X *
X */
Xint yesno(p1, p2)
Xregister char *p1, *p2;
X{
X	char reply[16];
X
X	fprintf(STDERR,"%s %s (y/n): ", p1, p2);
X	reply[0] = 16;
X#ifndef REMOTE
X	Cconrs(reply);
X#else
X	Cconraux(reply);
X#endif
X
X	putc('\n', STDERR);
X	return ( (reply[2] == 'y') || (reply[2] == 'Y') );
X
X}
X
X/*
X * copy files
X *	Usage:
X *		cp src dest
X *	    or
X *		cp files.. directory
X */
Xint cp(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char dest[128];
X	register int status;
X	extern int strlen();
X	extern int cpy();
X	extern char *basename();
X	
X	status = 0;
X	if(argc > 3)
X	{
X		register int i;
X
X		if(!existd(argv[argc-1]))
X		{
X			fprintf(STDERR,"%s does not exists or is not a directory\n",
X				argv[argc-1]);
X			return 1;
X		}
X
X		for(i = 1; i < argc - 1; i++)
X		{
X			strcpy(dest, argv[argc-1]);
X			if( (argv[argc-1])[(strlen(argv[argc-1])-1)] != '\\')
X				strcat(dest, "\\");
X			strcat(dest, basename(argv[i]));
X
X			fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
X			status |= cpy(argv[i], dest);
X		}
X	}
X	else
X	{
X		if(argc > 2)
X		{
X			if(existd(argv[2]))
X			{
X				/* dest is a directory */
X				strcpy(dest, argv[2]);
X				if( (argv[2])[(strlen(argv[2])-1)] != '\\')
X					strcat(dest, "\\");
X
X				strcat(dest, basename(argv[1]));
X
X				fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
X				return (cpy(argv[1], dest));
X			}
X
X			if(strcmp(argv[1], argv[2]) == 0)
X			{
X				fprintf(STDERR,"Cannot copy a file onto itself\n");
X				return 3;
X			}
X			status = cpy(argv[1], argv[2]);
X		}
X		else
X		{
X			fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
X			return 2;
X		}
X	}
X
X	return status;
X}
X
X
X/*
X * Cpy src -> dest
X *
X */
Xint cpy(src, dest)
Xchar *src, *dest;
X{
X	register int fps,fpd;
X	register long count;
X	register int status;
X
X	status = 0;
X
X	if((fps = Fopen(src, 0)) < (-3))
X	{
X		status = fps;
X		fprintf(STDERR,"%s: no such file\n", src);
X		return status;
X	}
X
X	if((fpd = Fcreate(dest, 0)) < (-3))
X	{
X		if((fpd = Fopen(dest, 1)) < (-3))
X		{
X			Fclose(fps);
X			status = fpd;
X			fprintf(STDERR,"%s: cannot create\n",dest);
X			return status;
X		}
X	}
X	
X	while( (count = Fread(fps, (long)BBUFSIZ, bufr)) > 0L)
X	{
X		if(Fwrite(fpd, count, bufr) != count)
X		{
X			status = 1;
X			fprintf(STDERR,"Error Writing %s\n",dest);
X			break;
X		}
X	}
X	if(count < 0L)
X	{
X		status = 2;
X		fprintf(STDERR,"Error Reading %s\n", src);
X	}
X
X	Fclose(fpd);
X	Fclose(fps);
X
X	return status;
X}
X
X#define haswild(X) \
X( (rindex(X,'*') != (char *)NULL) || (rindex(X,'?') != (char *)NULL) )
X
X/*
X * list directories
X */
Xint ls(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char path[128];
X	register char *p;
X	extern char *rindex();
X	extern int existd();
X
X	if(argc < 2)
X		lis("*.*");
X	else
X	{
X		while(--argc)
X		{
X			++argv;
X			if((p = rindex(*argv,'\\')) == (char *)NULL)
X				p = *argv;
X			else
X				p++;
X			if(*p == '\0')
X			{
X				strcpy(path, *argv);
X				strcat(path,"*.*");
X			}
X			else
X			{
X				if(haswild(p))
X					strcpy(path, *argv);
X				else
X				{
X					if(existd(p))
X					{
X						strcpy(path, *argv);
X						strcat(path, "\\*.*");
X					}
X					else
X						strcpy(path, *argv);
X				}
X			}
X			lis(path);
X		} /* while */
X	}
X	
X	return 0;
X}
X
X/*
X * given a possibly wild carded string put out list of subtrees
X *
X */
Xlis(wild)
Xchar *wild;
X{
X	extern struct stat statbuf;
X	register int count;
X
X#ifdef DEBUG
Xprintf("ls %s\n", wild);
X#endif
X
X	if(Fsfirst(wild, 0x0020 | 0x0010) != 0)
X	{
X		fprintf(STDERR,"%s - no match.\n", wild);
X		return;
X	}
X
X	count = 0;
X	alltolower(statbuf.st_name);
X	if(!((strcmp(statbuf.st_name,".") == 0) || 
X	   (strcmp(statbuf.st_name, "..") == 0)))
X		putls(&statbuf, ++count);
X
X	while(Fsnext() == 0)
X	{
X		alltolower(statbuf.st_name);
X		if(!((strcmp(statbuf.st_name,".") == 0) || 
X		   (strcmp(statbuf.st_name, "..") == 0)))
X			putls(&statbuf, ++count);
X	}
X
X	if((count % 4))
X		putc('\n', STDERR);
X
X}
X
X/*
X * Put out a directory entry
X */
Xputls(statbuf, count)
Xregister struct stat *statbuf;
Xregister int count;
X{
X	char dbuf[16];
X
X	if((statbuf->st_mode) & 0x0010)
X	{
X		/* subtree */
X		strcpy(dbuf, statbuf->st_name);
X		strcat(dbuf, "/");
X		fprintf(STDERR,"%-13s      ", dbuf);
X	}
X	else
X		/* file */
X		fprintf(STDERR,"%-12s %5ld ", statbuf->st_name, statbuf->st_size);
X	
X	if(!(count %4))
X		putc('\n', STDERR);
X}
X
X/*
X * Change working directory
X */
Xint cd(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register char *d, *path;
X	register int drive;
X	extern char *index();
X
X	if((argc < 2) || (argc > 2))
X	{
X		fprintf(STDERR,"Usage: cd directory\n");
X		return 1;
X	}
X
X
X	
X	if((d = index(argv[1],':')) == (char *)NULL)
X	{
X		/* Drive was not specified, must mean the current drive */
X		path = argv[1];
X	}
X	else
X	{
X		d--;
X		if(isupper(*d))
X		{
X			*d = tolower(*d);
X		}
X		drive = *d - 'a';
X		if(d[2] != '\\')	/* just gave D: */
X		{
X			/* we will shove in the '\' */
X			d[1] = '\\';
X			path = &d[1];
X		}
X		else
X			path = &d[2];
X
X		/* Set the Drive */
X		if(Dsetdrv(drive) < 0)
X		{
X			fprintf(STDERR,"Could not set drive %c:\n", *d);
X			return 2;
X		}
X
X	}
X
X
X	/* Set the Path */
X	if(Dsetpath(path) != 0)
X	{
X		fprintf(STDERR,"Could not set directory %s\n", path);
X		return 3;
X	}
X	
X	return 0;
X	
X}
X
X/*
X * pwd - figure out the current working directory
X *
X */
Xint pwd()
X{
X	register int drive;
X	char _cwd[128];
X	
X	drive = Dgetdrv();
X	Dgetpath(&_cwd[3],0);
X	fprintf(STDERR,"%c:%s%s\n", (drive + 'a'),
X		((_cwd[3] == '\\')? "" : "\\"), &_cwd[3]);
X
X	return 0;
X}
X
X/*
X * Print free space
X */
Xint df(argc, argv)
Xint argc;
Xchar **argv;
X{
X	struct {
X	    long b_free;
X	    long b_total;
X	    long b_secsiz;
X	    long b_clsiz;
X	} fbuf;
X
X	register int drive;
X	register long ffree, total;
X	extern long drv_map;
X
X	if(argc > 1)
X	{
X		++argv;
X		drive = (*argv)[0];
X		if(isupper(drive))
X			drive = tolower(drive);
X
X		drive = drive - 'a';
X		if((drv_map & (1L << drive)) == 0)
X		{
X			fprintf(STDERR,"Invalid Drive %c:\n", (drive + 'a'));
X			return 1;
X		}
X		drive +=1;
X	}
X	else
X		drive = Dgetdrv()+1;	/* default current drive */
X
X	fprintf(STDERR,"Please Wait .....");
X	Dfree(&fbuf,drive);
X	ffree = fbuf.b_free * fbuf.b_clsiz * fbuf.b_secsiz;
X	total =	fbuf.b_total * fbuf.b_clsiz * fbuf.b_secsiz;
X	fprintf(STDERR,"\r%ld Bytes (", ffree);
X	prratio(STDERR, ffree, total);
X	fprintf(STDERR, ") Free on drive %c:\n", ((drive-1) + 'a'));
X
X	return 0;
X}
X
X
X/*
X * print a ratio
X * avoid floats like the plague
X */
Xprratio(stream, num, den)
XFILE *stream;
Xlong  num, den;
X{
X        register int q;                 /* Doesn't need to be long */
X
X        if(num > 214748L) {             /* 2147483647/10000 */
X                q = num / (den / 10000L);
X        } else {
X                q = 10000L * num / den;         /* Long calculations, though */
X        }
X        if (q < 0) {
X                putc('-', stream);
X                q = -q;
X        }
X        fprintf(stream, "%d.%02d%%", q / 100, q % 100);
X}
X
X/*
X * Make directories
X */
Xint md(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register int status, s;
X
X	status = 0;
X	while(--argc)
X	{
X		++argv;
X		if(( s = Dcreate(*argv)))
X		{
X			status |= s;
X			fprintf(STDERR,"Could not create %s\n", *argv);
X		}
X	}
X
X	return status;
X}
X
X/*
X * Remove directories
X */
Xint rd(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register int status, s;
X
X	status = 0;
X	while(--argc)
X	{
X		++argv;
X		if(( s = Ddelete(*argv)))
X		{
X			status |= s;
X			fprintf(STDERR,"Could not delete %s\n", *argv);
X		}
X	}
X
X	return status;
X}
X
X
X/*
X * Allocate memory with error check
X *
X */
Xchar *myalloc(size)
Xunsigned int size;
X{
X	register char *m;
X	extern char *malloc();
X
X	if((m = malloc(size)) == (char *)NULL)
X	{
X		fprintf(STDERR,"Out of Memory\nSorry, cannot continue\n");
X		exit(1);
X	}
X
X	return m;
X}
X
X/*
X * Put out help
X */
Xint hhelp()
X{
X	register int i;
X
X#ifdef REMOTE
X	fprintf(STDERR,"\n\t\t\t    Available Commands \n\n");
X#else
X	fprintf(STDERR,"\n\t\t\t   \033p Available Commands \033q\n\n");
X#endif
X	for(i = 0; comtab[i].command != (char *)NULL; i++)
X	{
X		fprintf(STDERR,"\t%s\t%s\n", comtab[i].command,
X			comtab[i].synopsis);
X	}
X	fprintf(STDERR,"\n\tor hit <RETURN> to exit to terminal emulator\n\n");
X	return 0;
X
X}
X
X/*
X * Lower case string
X */
Xchar *alltolower(s)
Xregister char *s;
X{
X	register char *p;
X
X	for(p = s; *p != '\0'; p++)
X	{
X		if(isupper(*p))
X			*p = tolower(*p);
X	}
X	return s;
X}
X
X/*
X * return the base filename, given (potentially) a pathname
X */
Xchar *basename(s)
Xregister char *s;
X{
X	register char *p;
X	extern char *rindex();
X
X	if((p = rindex(s, '\\')) == (char *)NULL)
X	{
X		if((p = rindex(s, ':')) == (char *)NULL)
X			return s;
X		else
X			return ++p;
X	}
X	return ++p;
X}
X
X#ifdef RECURSE
Xint doszf(argc, argv)
Xint argc;
Xchar **argv;
X{
X	extern int expandargs();
X#ifdef DDEBUG
Xint i;
Xprintf("doszf: argc %d\n", argc);
Xfor(i = 0; i < argc; i++)
X	printf("%s ", argv[i]);
Xprintf("\n\n");
X#endif
X
X	return(expandargs(dosz, argc, argv));
X}
X
X#include "expandar.c"
X
X#endif
X
X#ifdef REMOTE
X/*
X * Read a line from the Aux port
X *
X */
X
XCconraux(l)
Xchar *l;
X{
X	register int c;
X	register int count;
X	register char *p;
X
X	p = &l[2];
X	count = 0;
X
X	while((c = get_a_c()) != '\n')
X	{
X		*p++ = c;
X		count++;
X	}
X	l[1] = count;
X}
X
Xstatic char _chr_buf[128];
Xstatic int _n_chr = 0;
Xstatic char *_next_chr = &_chr_buf[0];
Xstatic char *_next_avail = &_chr_buf[0];
X
Xint get_a_c()
X{
X        register int c;
X
X        if(_n_chr > 0)
X        {
X                _n_chr--;
X                return(*_next_avail++);
X        }
X        
X        _n_chr = 0;
X        _next_avail = &_chr_buf[0];
X        _next_chr = &_chr_buf[0];
X
X        while( ((c = Bconin(1) & 0x7fff) != '\r') && (c != '\n'))
X        {
X                if((c == '\003') || (c == '\025'))
X                {
X			while(_n_chr-- > 0)
X				wr_modem("\b \b");
X                        _n_chr = 0;
X                        _next_avail = &_chr_buf[0];
X                        _next_chr = &_chr_buf[0];
X
X                }
X
X                if((c == '\b') || (c == '\177'))
X                {
X                        if(_n_chr > 0)
X                        {
X                                _next_chr--;
X                                _n_chr--;
X                                wr_modem("\b \b");
X                        }
X                }
X                else
X                {
X                        *_next_chr++ = c;
X                        _n_chr++;
X			Bconout(1, c);
X                }
X        }
X
X        *_next_chr = '\n';
X        return(*_next_avail++);
X}
X#endif /* REMOTE */
X
X/* -eof- */
SHAR_EOF
chmod 0600 TRANSFER.C || echo "restore of TRANSFER.C fails"
echo "x - extracting TYME.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > TYME.C &&
X/*
X * 	Time conversions Module
X *
X *		Jwahar Bammi
X *			usenet: mandrill!bammi@{decvax,sun}.UUCP
X *			csnet:  bammi@mandrill.ces.CWRU.edu
X *			arpa:   bammi@mandrill.ces.CWRU.edu
X *			CompuServe: 71515,155
X */
X
X#include "config.h"
X#include <stdio.h>
X
X
X/*
X * days in a given year
X */
X#define days_in_year(Y) (leap(Y) ? 366 : 365)
X
X/* # of days / month in a normal year */
Xstatic unsigned int md[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
X
Xstatic int leap (y)
Xint y;
X{
X	y += 1900;
X	if ((y % 400) == 0)
X	    return (1);
X	if ((y % 100) == 0)
X	    return (0);
X	return ((y % 4) == 0);
X}
X
X/* Return the number of days between Jan 1, Given Year and the given
X * broken-down time.
X */
X
Xstatic unsigned long ndays (since, year, month, day)
Xunsigned int year, month, day;
X{
X	register unsigned long n = day;
X	register unsigned int m, y;
X	
X	for (y = since; y < year; y++)
X	{
X		n += 365;
X		if (leap (y)) n++;
X	}
X	for (m = 0; m < (month-1); m++)
X	    n += md[m] + ( ((m == 1) && leap(y))? 1 : 0);
X
X	return (n);
X}
X
X/* Convert a broken-down time into seconds
X *
X */
X
Xunsigned long tm_to_time (base_year, year, month, day, hours, mins, secs)
Xunsigned int base_year, year, month, day, hours, mins, secs;
X{
X	register unsigned long t;
X	extern unsigned long ndays();
X	
X	t = (ndays(base_year, year, month, day) - 1L) * (unsigned long)86400L
X	    + hours * (unsigned long)3600L + mins * (unsigned long)60L + secs;
X
X	return t;
X}
X
X/*
X * Convert ST time to Unix time
X *
X */
Xunsigned long st2unix(time, date)
Xunsigned int time, date;
X{
X	extern unsigned long tm_to_time();
X	
X	unsigned int yr = ((date >> 9) & 0x007f) + 80;  /* dissect the date */
X	unsigned int mo = (date >> 5) & 0x000f;
X	unsigned int dy = date & 0x1f;
X	
X	unsigned int hr = (time >> 11) & 0x001f;        /* dissect the time */
X	unsigned int mm = (time >> 5)  & 0x003f;
X	unsigned int ss = (time & 0x001f) * 2;
X
X#ifdef SDEBUG
X	printf("%d/%d/%d  %d:%d:%d\n", mo, dy, yr,hr, mm, ss);
X#endif
X	return (tm_to_time(70, yr, mo, dy, hr, mm, ss) -
X		(unsigned long)GMTDIFF);
X}
X
X/*
X * Convert Unix Time to ST Time
X *
X */
Xvoid unix2st(Unix, time, date)
Xunsigned long Unix;
Xunsigned int *date, *time;
X{
X	long stbase;
X	unsigned int hours, yrs, day, months, mins, seconds, t;
X	long days, secs;
X	extern unsigned long tm_to_time();
X
X#ifdef DEBUG
Xprintf("\n\nUnix Time %ld\n", Unix);
X#endif
X
X	
X	if((Unix - tm_to_time(70, 80, 0, 0, 0, 0, 0)) <= 0)  /* base 1980 */
X	{
X		/* thats before St's time */
X		*time = 0;
X		*date = (1 << 5) | 1;	/* Jan 1, 1980 00:00:00 GMT */
X#ifdef DEBUG
Xprintf("Before my time\n");
X#endif
X		return;
X	}
X
X	stbase = Unix;	/* do from base year 1970 */
X
X	days = stbase / 86400L;	/* 3600*24 */
X	secs = stbase % 86400L + GMTDIFF;
X	if(secs < 0)	/* previous day here */
X	{
X		days -= 1;
X		secs += 86400L;
X	}
X
X	/* extract hrs : mins : seconds */
X	hours = secs / 3600;
X	secs = secs - (hours * 3600);
X	mins = secs / 60;
X	seconds = secs - (mins * 60);
X	seconds &= ~1L;			/* ST has 2 sec resolution */
X
X	/* get the year and day of the year */
X	for(t = 70; days >= days_in_year(t); t++)
X		days -= days_in_year(t);
X	yrs = t;
X	day = days;
X
X	/* get the month */
X	if(days_in_year(yrs) == 366)
X		md[1] = 29;
X
X	for(t = 0; day >= md[t]; t++)
X		day -= md[t];
X
X	md[1] = 28;		
X	day = day + 1;
X	months = t + 1;
X
X#ifdef DEBUG
Xprintf("%d/%d/%d   %d:%d:%d\n", months, day, yrs, hours, mins, seconds);
X#endif
X
X	yrs -= 80;
X	*date = (((yrs & 0x007f) << 9) | ((months & 0x000f) << 5)
X	      | (day & 0x001f));
X	
X	*time = (((hours & 0x001f) << 11) | ((mins & 0x003f) << 5)
X	      | (seconds & 0x001e));
X}
X
X#ifdef TEST
X#include <stdio.h>
X#include <osbind.h>
X
Xmain()
X{
X	unsigned int time, date;
X	unsigned long Unix;
X	extern unsigned long st2unix();
X	
X	time = Tgettime();
X	date = Tgetdate();
X	Unix = st2unix(time, date);
X
X	printd(time, date);
X	printf("Unix Time %ld\n", Unix);
X
X	unix2st(Unix, &time, &date);
X	printd(time, date);
X}
X
Xprintd(time, date)
Xunsigned int time, date;
X{
X	
X	unsigned int yr = ((date >> 9) & 0x007f) + 80;  /* dissect the date */
X	unsigned int mo = (date >> 5) & 0x000f;
X	unsigned int dy = date & 0x1f;
X	
X	unsigned int hr = (time >> 11) & 0x001f;        /* dissect the time */
X	unsigned int mm = (time >> 5)  & 0x003f;
X	unsigned int ss = (time & 0x001f) * 2;
X
X	printf("%d/%d/%d\t%d:%d:%d\n", mo, dy, yr, hr, mm, ss);
X}
X#endif /* TEST */
X
X/* -eof- */
SHAR_EOF
chmod 0600 TYME.C || echo "restore of TYME.C fails"
echo "x - extracting UTIL.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > UTIL.C &&
X/*
X * 	Utilities Module
X *
X *		Jwahar Bammi
X *			usenet: mandrill!bammi@{decvax,sun}.UUCP
X *			csnet:  bammi@mandrill.ces.CWRU.edu
X *			arpa:   bammi@mandrill.ces.CWRU.edu
X *			CompuServe: 71515,155
X */
X
X
X#include "config.h"
X#include "zmdm.h"
X
X#ifndef Vsync 			/* Atari forgot these in osbind.h */
X#define Vsync()	xbios(37)
X#endif
X
X#define GOTO(r,c)	EscSeq('Y');Bconout(2, r+040);Bconout(2, c+040)
X
X 	/* External Variables */
Xlong     pr_time   = 0L;	  /* Present time	  (200 Hz) */ 
X
X#ifndef STANDALONE
X#ifndef REMOTE
Xextern int  *aline_addr; /* Ptr to base of Aline variables */
Xextern long *ms_ptr;	/* pointer to my screen memory aligned to a 256
X			   byte boundary */
X
X 	/* Globals */
Xstatic char *hs_ptr;   /* pointer to his screen memory */
Xstatic int  x_saved, y_saved;	/* Saved cursor position */
X#endif
X#endif
X
Xstatic long *hz_200 =  (long *)0x000004ba; /* Yes the Hitch Hikers */
X					   /* Guide is wrong!! */
X
X/*
X * rd_time() - read the value of the systems 200 Hz counter
X * must be called in Super Mode else you get
X * what you deserve - MUSHROOMS!!
X */
Xvoid rd_time()
X{
X	pr_time = *hz_200;
X}
X
X#ifndef STANDALONE
X/*
X * my_screen() - Start using my screen memory
X * for all output.
X *
X */
Xvoid my_screen()
X{
X#ifndef REMOTE
X	/* The cursor position has been saved prior to calling this routine */
X	x_saved = aline_addr[-14];
X	y_saved = aline_addr[-13];
X
X	/* save his screen memory pointer */
X	hs_ptr = (char *)Logbase();
X	
X	/* switch to my display memory */
X	Setscreen(ms_ptr, ms_ptr, -1);
X#else
X	wr_modem("\r\n\n");
X#endif
X}
X
X
Xvoid his_screen()
X{
X#ifndef REMOTE
X	/* switch to his Screen memory, wait for a Vblank, so
X	 * that the Logical Loc == Physical Loc, then pop saved
X	 * cursor */
X	Setscreen(hs_ptr, hs_ptr, -1);
X	Vsync();
X	Vsync();	/* starts happening at the last one */
X	GOTO(y_saved, x_saved);
X#else
X	wr_modem("\r\n\n");
X#endif
X	
X}
X
X/*
X * hit_key() - wait for the user to hit a key
X * 
X */
Xvoid hit_key()
X{
X#ifndef REMOTE
X	Bconws("\r\n\033pHit Any Key To Continue .....\033q");
X	Bconin(2);
X	Bconws("\r\n");
X#else
X	wr_modem("\r\nHit Any Key To Continue .....");
X	Bconin(1);
X	wr_modem("\r\n");
X#endif
X}
X#endif /* STANDALONE */
X
X/*
X * find the size of a file given its name
X */
Xlong filesize(name)
Xregister char *name;
X{
X	extern struct stat statbuf;
X	
X	if(Fsfirst(name,(int)(0x01 | 0x020)) != 0)
X	{
X		return 0L;
X		
X	}
X
X	return statbuf.st_size;
X}
X
X
X/*
X * Write a string to console
X */
XBconws(s)
Xregister char *s;
X{
X	while(*s)
X		Bconout(2, *s++);
X}
X
X#ifndef STANDALONE
X#ifndef REMOTE
X#ifndef MANX
X#ifndef MWC
X
X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */
X/*									   */
X/*  ALCYON C dependant, this routine must return the base address of	   */
X/*	of the linea variable block					   */
X/*									   */
X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */
X
X/*
X * return the base address of the line A variables 
X */
Xint *aaddress()
X{
X	asm("dc.w $A000");	/* Line A trap - 0000 is init aline  */
X				/* d0 and a0 now contain the address */
X				/* so we can just return and the result
X				 * will be valid
X				 */
X}
X
X
X/*
X *  Make hi rez screen bios handle 50 lines of 8x8 characters
X *
X * Adapted to C use from origonal asm posting
X *
X */
Xhi50()
X{
X	/* Switch to 50 lines display */
X
X	asm(".dc.w    $a000");		/* get the important pointers */
X
X	asm("move.l  04(a1),a1");	/* a1 -> 8x8 font header */
X
X	asm("move.l  72(a1),-$0A(a0)");	/* v_off_ad <- 8x8 offset table addr */
X	asm("move.l  76(a1),-$16(a0)");	/* v_fnt_ad <- 8x8 font data addr */
X
X	asm("move.w  #008,-$2E(a0)");	/* v_cel_ht <- 8    8x8 cell height */
X	asm("move.w  #049,-$2A(a0)");	/* v_cel_my <- 49   maximum cell "Y" */
X	asm("move.w  #640,-$28(a0)"); /* v_cel_wr <- 640  offset to cell Y+1 */
X
X}
X   
X/*
X * Make hi rez screen bios handle 25 lines of 8x16 characters
X *
X */
Xhi25()
X{
X	
X	/* Switch to 25 lines display */
X
X
X	asm(".dc.w    $a000");		/* get the important pointers */
X	
X	asm("move.l  08(a1),a1");	/* a1 -> 8x16 font header */
X
X	asm("move.l  72(a1),-$0A(a0)");	/* v_off_ad <- 8x16 offset table addr */
X	asm("move.l  76(a1),-$16(a0)");	/* v_fnt_ad <- 8x16 font data addr */
X
X	asm("move.w  #0016,-$2E(a0)");	/* v_cel_ht <- 16    8x16 cell height */
X	asm("move.w  #0024,-$2A(a0)");	/* v_cel_my <- 24    maximum cell "Y" */
X	asm("move.w  #1280,-$28(a0)");	/* v_cel_wr <- 1280  vertical byte offset */
X}
X
X#else
X
X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */
X/*									   */
X/*     MWC  dependant, this routine must return the base address of	   */
X/*	of the linea variable block					   */
X/*									   */
X/* **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** **WARNING** */
X#include <linea.h>
X/*
X * return the base address of the line A variables 
X */
X
Xint *aaddress()
X{
X	linea0();	/* Init LineA - dumps returned values into la_init */
X	return (int *)(la_init.li_a0); /* Return address of Parameter Block */
X}
X
X		/* Mark Williams C 	   */
X		/* See file hi5025.s       */
X		/* for functions hi50()    */
X		/* and hi25()		   */
X#endif /* MWC */
X#endif /* MANX */
SHAR_EOF
echo "End of part 5"
echo "File UTIL.C is continued in part 6"
echo "6" > s2_seq_.tmp
exit 0