[comp.sources.atari.st] v01i043: zmdm -- terminal program with file transfer part03/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 43
Archive-name: zmdm/part03

#!/bin/sh
# this is part 3 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file MAIN.C continued
#
CurArch=3
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 MAIN.C"
sed 's/^X//' << 'SHAR_EOF' >> MAIN.C
X	{
X	    case 'B':
X	    case 'b':
X		/* Set baud rate */
X		setRs232();
X		break;
X		
X	    case 'T':
X	    case 't':
X	        Bauxws("\r\n\n");		/* clear screen */
X
X		    /* Set no flow Control */
X#ifdef FLOW_CTRL
X		    Rsconf(-1,0,-1,-1,-1,-1);
X		    Vsync(); Vsync();
X
X#endif
X		/* Go do transfers */
X		transfer();
X		    
X#ifdef FLOW_CTRL
X		    /* Flow Control On */
X/*		    Txoff(); */
X		    Rsconf(-1,1,-1,-1,-1,-1);
X		    Vsync(); Vsync();
X/*		    Txon(); */
X#endif
X		his_screen();
X		return;
X		
X	    case '\033':
X		/* Send a break */
X		sendbrk();
X		his_screen();	/* Don't wait for the key hit */
X
X		return;
X
X		/* else fall Through */
X		
X	    default:
X		Bauxws("No Change\r\n");
X	}
X
X	/* back to terminal screen */
X	his_screen();
X}
X#endif /* REMOTE */
X
Xmain ()
X{
X	register int	c;		/* rs232 input */
X	register int	i;
X	register long	conin;
X#ifndef REMOTE
X	extern int *aaddress(); /* Routine that returns base address of
X				 * line A variables
X				 */
X#else
X	extern FILE *fopen();
X#endif
X
X#ifdef MWC
X	extern char *lmalloc();
X#endif
X
X	/* Set up Dta */
X	Fsetdta(&statbuf);
X
X	/* Get screen rez */
X	rez = Getrez();
X	drv_map = Drvmap();
X
X#if (MWC || MANX)
X#ifndef REMOTE
X#ifdef MWC
X       if((m_screen = (long *)lmalloc(
X	               (unsigned long)((8L*1024L+32L)*(long)sizeof(long))))
X							== (long *)NULL)
X#else
X       if((m_screen = (long *)Malloc(
X	               (unsigned long)((8L*1024L+32L)*(long)sizeof(long))))
X							== (long *)NULL)
X#endif
X	{
X		Bconws("Sorry, could not allocate enough memory\r\n");
X		Pterm(3);
X	}
X#endif /* REMOTE */
X#ifndef DYNABUF
X#ifdef MANX
X	if((bufr = (unsigned char *)Malloc((unsigned long)BBUFSIZ))
X					 == (unsigned char *)NULL)
X#else
X	if((bufr = (unsigned char *)lmalloc((unsigned long)BBUFSIZ))
X					 == (unsigned char *)NULL)
X#endif
X#else
X	if((bufr = dalloc()) == (unsigned char *)NULL)
X#endif /* DYNABUF */
X	{
X#ifdef REMOTE
X		Bauxws("Sorry, could not allocate enough memory\r\n");
X#else
X		Bconws("Sorry, could not allocate enough memory\r\n");
X#endif
X
X		Pterm(4);
X	}
X
X#else /* MWC || MANX */
X#ifdef DYNABUF
X	if((bufr = dalloc()) == (unsigned char *)NULL)
X	{
X#ifdef REMOTE
X		Bauxws("Sorry, could not allocate enough memory\r\n");
X#else
X		Bconws("Sorry, could not allocate enough memory\r\n");
X#endif
X		Pterm(5);
X	}
X#endif /* DYNABUF */
X#endif /* MWC || MANX */
X
X#ifndef REMOTE
X#if (MWC || MANX)
X	ms_ptr = (long *) ((0xffffff00L & ((long)(m_screen))) + 0x00000100L);
X#else
X	ms_ptr = (long *) ((0xffffff00L & ((long)(&m_screen[0]))) + 0x00000100L);
X#endif /* MWC */
X
X	EscSeq('e');		/* Turn on the cursor */
X	EscSeq('v');		/* wrap at end of line */
X	EscSeq('E');		/* clear screen */
X#endif /* REMOTE */
X
X	SetIoBuf();
X
X	speed = getbaud();
X/*	Txoff(); */
X	Rsconf((int) speed, flowctl, ucr, rsr, tsr, scr);  /* init set */
X	Vsync(); Vsync();
X/*	Txon();	 */
X
X	Baudrate = BAUD_RATE(speed);
X	
X#ifndef REMOTE
X	aline_addr = aaddress();
X	STDERR = stderr;
X#else
X#ifndef DLIBS
X	if((STDERR = fopen("aux:", "rw")) == (FILE *)NULL)
X	{
X		Bauxws("Could not Open Aux Stream for Stderr\r\n");
X		finish();
X	}
X	setbuf(STDERR, (char *)NULL);
X#else
X	STDERR = stdaux;
X#endif /* DLIBS */
X	
X#endif /* remote */
X
X	help();
X
X	i = 0;
X	while (0 == 0)	/* infinite loop */
X	{
X#ifndef REMOTE
X		while (Bconstat(rs232) != 0)
X		{
X			/* Char at Modem */
X			c = Bconin(rs232) & 0x007f;
X			Bconout(console, c);
X
X			/* Check the console once in a while */
X			/* important at High speeds */
X			if ((++i) & 32)
X			{
X			    if (Bconstat(console) != 0)
X	      		    {
X				    conin = Bconin(console);
X				    Bconout(rs232, (int) (conin & 0x007f));
X			    }
X			    i = 0;
X			}
X				
X		}
X		
X		if (Bconstat(console) != 0)
X		{
X			/* Char at Console */
X			conin = Bconin(console);
X			if ((conin & 0x00FF0000L) == 0x00610000L)  /* Undo */
X			{
X				ResetIoBuf();
X				finish();
X			}
X			
X			if ((conin & 0x00FF0000L) == 0x00620000L)  /* Help */
X			    help();
X			else
X			    Bconout(rs232, (int) (conin & 0x007f));
X		}
X#else
X		while (Bconstat(rs232) != 0)
X		{
X			/* Char at Modem */
X			c = Bconin(rs232) & 0x007f;
X
X			if ((c & CTRL('U')) == CTRL('U'))  /* Undo */
X			{
X				ResetIoBuf();
X				finish();
X			}
X			
X			if ((c & CTRL('Z')) == CTRL('Z'))  /* Help */
X			    help();
X			else
X			    Bconout(rs232,c);
X		}
X
X#endif /* REMOTE */
X	}
X}
X
Xfinish()
X{
X#ifdef PHONES
X	/* Save phone directory if it changed */
X	extern int dchanged;
X
X	if(dchanged)
X	{
X		if(writedir() == 1)
X		    hit_key();
X	}
X#endif
X
X#if (MWC || MANX)
X#ifdef DYNABUF
X	Mfree(bufr);
X#else
X	free(bufr);
X#endif
X
X#ifndef REMOTE
X	free(m_screen);
X#endif
X
X#else
X
X#ifdef DYNABUF
X	Mfree(bufr);
X#endif
X#endif
X	exit(0);
X}
X
X/* -eof- */
SHAR_EOF
echo "File MAIN.C is complete"
chmod 0600 MAIN.C || echo "restore of MAIN.C fails"
echo "x - extracting MAKEFALC.STA (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFALC.STA &&
X#
X# Makefile for Alcyon C (version 4.14 required) and STANDALONE versions
X#	of RZ and SZ.
X#	for use with PD MAKE distributed by us.
X#
X#	Fix paths below for your set up
X#		c:\include\	Path to include files
X#		c:\lib\		Path to C library files
X#
X#	Edit config.h before make'ing
X#
X#	Please use a decent version of gemstart.s that gives some
X#	breathing room to malloc()
X#
X#	Jwahar Bammi
X
XSRC = common.c rz.c sz.c util.c tyme.c zm.c fileio.c
XRZOBJ = common.o rz.o util.o tyme.o zm.o fileio.o
XSZOBJ = common.o sz.o util.o tyme.o zm.o fileio.o
X
XINCLUDE = c:\include
XLIB = c:\lib
XCPFLAGS = -i $(INCLUDE)\ -DDECL -DSTANDALONE
XLINKER = c:\bin\aln.prg
X
Xrz.prg : $(RZOBJ)
X	$(LINKER) -o rz.prg -c rzlnk
X
Xsz.prg : $(SZOBJ)
X	$(LINKER) -o sz.prg -c szlnk
X
X$(RZOBJ) : common.h zmdm.h decl.h config.h
X$(SZOBJ) : common.h zmdm.h decl.h config.h
X
Xclean:
X	$(RM) *.o *.68k
SHAR_EOF
chmod 0600 MAKEFALC.STA || echo "restore of MAKEFALC.STA fails"
echo "x - extracting MAKEFILE (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE &&
X#
X# Makefile for Mark Williams C
X#	Version 2.00 (or higher) required.
X#	Please ignore warnigs about a constant being promoted to long
X#	and about some unused variables.
X#	
X# 	Edit config.h before make'ing.
X#
X#	Jwahar Bammi
X#
X#
X
XSRC = common.c rz.c sz.c transfer.c util.c main.c tyme.c zm.c fileio.c \
Xhi5025.s phone.c
X
XOBJ =  fileio.o zm.o util.o rz.o sz.o common.o tyme.o transfer.o main.o \
Xhi5025.o phone.o
X
XCFLAGS = -O -V -VPEEP -DMWC=1
XLDFLAGS = -s -x -V
X
Xzmdm.prg : $(OBJ)
X	cc -O -o zmdm.prg $(OBJ) $(LDFLAGS)
X
X$(OBJ) : common.h zmdm.h decl.h config.h
Xtransfer.o : expandar.c
X
Xclean:
X	rm *.o
SHAR_EOF
chmod 0600 MAKEFILE || echo "restore of MAKEFILE fails"
echo "x - extracting MAKEFILE.ALC (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE.ALC &&
X#
X# Makefile for Alcyon C (version 4.14 required)
X#	for use with PD MAKE distributed by us.
X#
X#	Fix paths below for your set up
X#		c:\include\	Path to include files
X#		c:\lib\		Path to C library files
X#
X#	Edit config.h
X#	
X#	Please use a decent version of gemstart.s that gives some
X#	breathing room to malloc()
X#
X#	Jwahar Bammi
X
XSRC = common.c rz.c sz.c transfer.c util.c main.c tyme.c zm.c fileio.c dummy.c \
Xphone.c
X
XOBJ = common.o rz.o sz.o transfer.o util.o main.o tyme.o zm.o fileio.o dummy.o \
Xphone.o
X
XINCLUDE = c:\include
XLIB = c:\lib
XCPFLAGS = -i $(INCLUDE)\ -DDECL
XLINKER = c:\bin\aln.prg
X
Xzmdm.prg : $(OBJ)
X	$(LINKER) -o zmdm.prg -c lnk
X
X$(OBJ) : common.h zmdm.h decl.h config.h
Xtransfer.o : expandar.c
X
Xclean:
X	$(RM) *.o *.68k
SHAR_EOF
chmod 0600 MAKEFILE.ALC || echo "restore of MAKEFILE.ALC fails"
echo "x - extracting MAKEFILE.MAN (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE.MAN &&
X#
X# Makefile for Mark Williams C
X#	Version 2.00 (or higher) required.
X#	Please ignore warnigs about a constant being promoted to long
X#	and about some unused variables.
X#	
X# 	Edit config.h before make'ing.
X#
X#	Jwahar Bammi
X#
X#
X
XSRC = common.c rz.c sz.c transfer.c util.c main.c tyme.c zm.c fileio.c \
Xmanx.asm phone.c
X
XOBJ =  fileio.o zm.o util.o rz.o sz.o common.o tyme.o transfer.o main.o \
Xmanx.o phone.o
X
XCFLAGS = -DMANX=1
XLDFLAGS = -V
X
Xzmdm.prg : $(OBJ)
X	ln -o zmdm.prg $(LDFLAGS) $(OBJ) -Lc
Xmanx.o : manx.asm
X	as -V manx.asm
X
X$(OBJ) : common.h zmdm.h decl.h config.h
Xtransfer.o : expandar.c
X
Xclean:
X	rm *.o
SHAR_EOF
chmod 0600 MAKEFILE.MAN || echo "restore of MAKEFILE.MAN fails"
echo "x - extracting MAKEFILE.STA (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE.STA &&
X#
X# Makefile for Mark Williams C for standalone versions of RZ and SZ
X#	Version 2.00 required.
X#	Please ignore warnigs about a constant being promoted to long
X#	and about some unused variables.
X#
X#	Edit config.h before make'ing
X#
X#	Jwahar Bammi
X#
X#
XSRC = common.c rz.c sz.c util.c tyme.c zm.c fileio.c
XRZOBJ = common.o rz.o util.o tyme.o zm.o fileio.o
XSZOBJ = common.o sz.o util.o tyme.o zm.o fileio.o
X
XCFLAGS = -O -DSTANDALONE -DMWC=1 -V -VPEEP
XLDFLAGS = -x -s -V -VPEEP
X
Xrz.prg : $(RZOBJ)
X	cc -O -o rz.prg $(RZOBJ) $(LDFLAGS)
X
X$(RZOBJ) : common.h zmdm.h decl.h config.h
X
Xsz.prg : $(SZOBJ)
X	cc -O -o sz.prg $(SZOBJ) $(LDFLAGS)
X
X$(SZOBJ) : common.h zmdm.h decl.h config.h
X
Xclean:
X	rm *.o
SHAR_EOF
chmod 0600 MAKEFILE.STA || echo "restore of MAKEFILE.STA fails"
echo "x - extracting MAKEFMAN.STA (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAKEFMAN.STA &&
X#
X# Makefile for Manx Aztec C for standalone versions of RZ and SZ
X#	Version 3.6a tested.
X#
X#	Edit config.h before make'ing
X#
X#	Jwahar Bammi
X#
X#
XSRC = common.c rz.c sz.c util.c tyme.c zm.c fileio.c
XRZOBJ = common.o rz.o util.o tyme.o zm.o fileio.o
XSZOBJ = common.o sz.o util.o tyme.o zm.o fileio.o
X
XCFLAGS = -DSTANDALONE -DMANX=1
XLDFLAGS = -V
X
Xrz.prg : $(RZOBJ)
X	ln -o rz.prg $(LDFLAGS) $(RZOBJ) -Lc
X
X$(RZOBJ) : common.h zmdm.h decl.h config.h
X
Xsz.prg : $(SZOBJ)
X	ln -o sz.prg $(LDFLAGS) $(SZOBJ) -Lc
X
X$(SZOBJ) : common.h zmdm.h decl.h config.h
X
Xclean:
X	rm *.o
SHAR_EOF
chmod 0600 MAKEFMAN.STA || echo "restore of MAKEFMAN.STA fails"
echo "x - extracting MANX.ASM (Text)"
sed 's/^X//' << 'SHAR_EOF' > MANX.ASM &&
X;
X;  Make hi rez screen bios handle 50 lines of 8x8 characters
X;
X;  Adapted to Manx C use from origional PD asm posting
X;  from atari corp.
X;
X; 		Jwahar Bammi
X; 			usenet: cwruecmp!bammi@decvax.UUCP
X;			csnet:  bammi@cwru.edu
X;			arpa:   bammi@cwru.edu
X; 			CompuServe: 71515,155
X; 
X;
X	cseg
X
X	public _hi50
X
X_hi50:				  ; switch to 50 line mode
X	link	a6,#0		  ; routine preamble
X
X	dc.w	$A000		  ; get the important pointers (line A init)
X
X	movea.l    4(a1),a1	  ; a1 -> 8x8 font header
X
X	move.l  72(a1),-$0A(a0)   ; v_off_ad <- 8x8 offset table addr
X	move.l  76(a1),-$16(a0)   ; v_fnt_ad <- 8x8 font data addr
X
X	move    #8,-$2E(a0)	  ; v_cel_ht <- 8    8x8 cell height
X	move    #49,-$2A(a0)	  ; v_cel_my <- 49   maximum cell "Y"
X	move    #640,-$28(a0)     ; v_cel_wr <- 640  offset to cell Y+1
X
X	unlk	a6		  ; routine postable
X	rts			  ; and return
X
X   
X;
X; Make hi rez screen bios handle 25 lines of 8x16 characters
X;
X
X	public _hi25
X
X_hi25:				  ; Switch to 25 lines display
X	link	a6,#0		  ; routine preamble
X
X	dc.w    $A000		  ; get the important pointers
X	
X	movea.l    8(a1),a1	  ; a1 -> 8x16 font header
X
X	move.l  72(a1),-$0A(a0)   ; v_off_ad <- 8x16 offset table addr
X	move.l  76(a1),-$16(a0)   ; v_fnt_ad <- 8x16 font data addr
X
X	move    #16,-$2E(a0)	  ; v_cel_ht <- 16    8x16 cell height
X	move    #24,-$2A(a0)	  ; v_cel_my <- 24    maximum cell "Y"
X	move    #1280,-$28(a0)	  ;  v_cel_wr <- 1280  vertical byte offset
X
X	unlk	a6		  ; routine postamble
X	rts			  ; bye
X
X
X; return the base address of the line A variables 
X
X	public _aaddress
X
X_aaddress:
X	link	a6,#0
X	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	unlk	a6
X	rts
X
X	end
SHAR_EOF
chmod 0600 MANX.ASM || echo "restore of MANX.ASM fails"
echo "x - extracting PHONE.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > PHONE.C &&
X/*
X * Phone dialing Module (from XMDM)
X *
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#ifndef STANDALONE
X#ifdef PHONES
X
X#include "zmdm.h"
X
Xtypedef int WORD;
Xtypedef long LONG;
X
X
X#define sendchar(c)	Bconout(1, c);
X#define clear_screen()  Bconws("\033H\033J")
X#define inv()		EscSeq('p')
X#define normal()	EscSeq('q')
X#define mvto(r,c)	EscSeq('Y');Bconout(2, r+040);Bconout(2, c+040)
X#define ceol()		EscSeq('K')
X#define show_cursor()	EscSeq('e')
X#define hide_cursor()	EscSeq('f')
X
Xtypedef struct _dir {		/* The Directory type */
X	char	*name;		/* Name (11 chars max) */
X	char 	*number;	/* Phone # (24 chars max) */
X	WORD	baud;		/* baud Rate		 */
X	struct _dir *next;	/* Ptr to next entry */
X} *DIR;
X
X
X 	/* External Variables */
Xextern WORD speed;		/* Current Baud Rate */
Xextern WORD Baudrate;
Xextern BAUDS vbauds[];
X
XWORD dchanged = 0;			/* Has the directory been updated */
X
X 	/* Globals */
Xstatic WORD ndir = 0;			/* # of entries in phone directory   */
Xstatic DIR directory = (DIR)NULL;	/* The phone directory  	     */
Xstatic DIR lastdir   = (DIR)NULL; 	/* Pointer to last entry	     */
Xstatic char *dirfile = (char *)NULL;	/* Name of file conatining directory */
Xstatic WORD rflag = 0;			/* Read directory as yet?? 	     */
X
X
X/*
X * Read the Telephone directory
X *  returns -2 on read error
X *	    -1 if cancelled
X *	    -3 if file not found
X *	     n # of entries  otherwise
X */
XWORD readdir()
X{
X	register char *filename;
X	register WORD handle;
X	register WORD nentries;
X	register DIR last;
X	register DIR present;
X	extern char *preadl();
X	extern char *malloc();
X	
X	Bconws("Enter Filename of Phone Directory or <CR> to Cancel: ");
X
X	if((filename = preadl()) == (char *)NULL)
X	    /* Cancelled */
X	    return -1;
X
X	if((dirfile = malloc(strlen(filename)+1)) == (char *)NULL)
X	{
X		/* Out of memory */
X		Bconws("Out of Memory\r\n");
X		return 0;
X	}
X	strcpy(dirfile,filename);
X	
X
X	if((handle = Fopen(filename,0)) < 0)
X	    /* File does not exist */
X	    return -3;
X	
X	/* Read in the file */
X	if(Fread(handle, 2L, &ndir) != 2L)
X	{
X		Bconws("Error Reading ");
X		Bconws(filename);
X		Bconws("\r\n");
X		Fclose(handle);
X		return -2;
X	}
X
X	/* Read in the directory */
X	last = (DIR)NULL;
X	directory = (DIR)NULL;
X	lastdir = (DIR)NULL;
X	rflag = 1;
X	
X	for(nentries = 0; nentries < ndir; nentries++)
X	{
X		/* Allocate an entry */
X		if((present = (DIR)malloc(sizeof(struct _dir))) == (DIR)NULL)
X		{
X			/* Out of memory */
X			Bconws("Out of Memory\r\n");
X			Fclose(handle);
X			return nentries;
X		}
X		
X		if((present->name = malloc(12)) == (char *)NULL)
X		{
X			/* Out of memory */
X			Bconws("Out of Memory\r\n");
X			Fclose(handle);
X			return nentries;
X		}
X
X		if((present->number = malloc(25)) == (char *)NULL)
X		{
X			/* Out of memory */
X			Bconws("Out of Memory\r\n");
X			Fclose(handle);
X			return nentries;
X		}
X
X		present->next = (DIR)NULL;
X		
X		/* Read in the entry */
X		if(Fread(handle,11L,present->name) != 11L)
X		{
X			Bconws("Error Reading ");
X			Bconws(filename);
X			Bconws("\r\n");
X			Fclose(handle);
X			rflag = 0;
X			freedir(directory);
X			return -2;
X
X		}
X
X		if(Fread(handle,24L,present->number) != 24L)
X		{
X			Bconws("Error Reading ");
X			Bconws(filename);
X			Bconws("\r\n");
X			Fclose(handle);
X			rflag = 0;
X			freedir(directory);
X			return -2;
X		}
X
X		if(Fread(handle,2L,&(present->baud)) != 2L)
X		{
X			Bconws("Error Reading ");
X			Bconws(filename);
X			Bconws("\r\n");
X			Fclose(handle);
X			rflag = 0;
X			freedir(directory);
X			return -2;
X		}
X		
X
X		present->name[11] = '\0';
X		present->number[24] = '\0';
X
X		/* Link it on with the directory */
X		if(last == (DIR)NULL)
X			/* first entry */
X			directory = present;
X		else
X			last->next = present;
X		
X		last = present;
X	}
X	lastdir = last;
X	
X	return nentries;	
X}
X
X/*
X * Free space allocated to a phone directory
X *
X */
Xfreedir(dir)
Xregister DIR dir;
X{
X	register DIR next;
X	register DIR present;
X
X	for(present = dir; present != (DIR)NULL; present = next)
X	{
X		next = present->next;
X		free(present->name);
X		free(present->number);
X		free(present);
X	}
X	
X	if(dirfile != (char *)NULL)
X	{
X		free(dirfile);
X		dirfile   = (char *)NULL;
X	}
X	
X	directory = (DIR)NULL;
X	lastdir	  = (DIR)NULL;
X	ndir	  = 0;
X	rflag	  = 0;
X}
X
X/*
X * Write out the phone directory
X *  -returns 0 on success 1 otherwise
X *
X */
XWORD writedir()
X{
X	register DIR dir;
X	register WORD fd;
X	
X	if((rflag == 0) || (dirfile == (char *)NULL) || (dchanged == 0))
X	    /* Nothing to Save */
X	    return 0;
X
X	/* Create/Open file for write - overwrite if it exists */
X	if ((fd = Fcreate(dirfile,0)) < 0) /* Will fail if file is present */
X	{
X		/* Overwrite existing file */
X		if((fd = Fopen(dirfile,1)) < 0)
X		{
X			Bconws("Cannot Open ");
X			Bconws(dirfile);
X			Bconws("\r\n");
X			return 1;
X		}
X	}
X
X	if(Fwrite(fd,2L,&ndir) != 2L)
X	{
X		Bconws("Error Writing ");
X		Bconws(dirfile);
X		Bconws("\r\n");
X		Fclose(fd);
X		return 1;
X	}
X	
X	for(dir = directory; dir != (DIR)NULL; dir = dir->next)
X	{
X		if(Fwrite(fd,11L,dir->name) != 11L)
X		{
X			Bconws("Error Writing ");
X			Bconws(dirfile);
X			Bconws("\r\n");
X			Fclose(fd);
X			return 1;
X		}
X
X		if(Fwrite(fd,24L,dir->number) != 24L)
X		{
X			Bconws("Error Writing ");
X			Bconws(dirfile);
X			Bconws("\r\n");
X			Fclose(fd);
X			return 1;
X		}
X
X		if(Fwrite(fd,2L,&(dir->baud)) != 2L)
X		{
X			Bconws("Error Writing ");
X			Bconws(dirfile);
X			Bconws("\r\n");
X			Fclose(fd);
X			return 1;
X		}
X	}
X	
X	Fclose(fd);
X	return 0;
X}
X
X/*
X * Show the phone directory
X * return the entry # or -1 if cancelled
X *
X */
XWORD showdir()
X{
X	register WORD first, last;
X	register WORD n;
X	register char *line;
X	extern WORD atoi();
X	extern char *preadl();
X	
X	first = 0;
X
X	while(1)
X	{
X	    again:
X		clear_screen();
X
X		mvto(0,19);
X		Bconws("Phone Directory: ");
X		Bconws(dirfile);
X		Bconws("  ");
X		printf("%d",ndir); fflush(stdout);
X		Bconws(" Entry(s)");
X
X		last = (ndir < (first + 44)) ? ndir : first + 44;
X		putdir(first,last);
X		
X		/* mvto(25,0); */
X		Bconws("\r\n");
X		inv();
X		Bconws("Enter a # or <SPACE><RETURN> for Next Page or <RETURN> to Cancel:");
X		normal();
X		Bconout(2, ' ');
X		if((line = preadl()) == (char *)NULL)
X		{
X			return -1;
X		}
X		
X		if(isdigit(*line))
X		{
X			if((n = atoi(line)) >= ndir)
X			{
X				Bconws("Invalid Number ");
X				hit_key();
X				goto again;
X			}
X		    
X			return n;
X		}
X
X		if(last == ndir)
X		    first = 0;
X		else
X		    first += 44;
X	}
X}
X
X/*
X * Put up directory entries on the screen
X *
X */
Xputdir(first,last)
Xregister WORD first;
Xregister WORD last;
X{
X	register DIR dir;
X	register WORD row;
X	extern DIR nth();
X	
X	/* Find the first entry */
X	dir = nth(first);
X	row = (first % 44) + 1;
X
X	hide_cursor();
X	inv();
X	for(; first < last; first++)
X	{
X		mvto(row,((first & 1)?41:0));
X		if(first < 10)
X			Bconout(2, ' ');
X		printf("%d",first); fflush(stdout);
X		Bconout(2, '|');
X		putstr(dir->name,11);
X		Bconout(2, '|');
X		putstr(dir->number,24);
X		dir = dir->next;
X		if(first & 1)
X			row++;
X	}
X
X	if(first & 1)
X	{
X		mvto(row,41);
X		Bconws("  |           |                        ");
X		row++;
X	}
X
X	for(; row < 23; row++)
X	{
X		Bconws("  |           |                        ");
X		mvto(row,41);
X		Bconws("  |           |                        ");
X	}
X
X	normal();
X	show_cursor();
X}
X
X/*
X * Put a string padding to len on screen
X */
Xputstr(s,l)
Xregister char *s;
Xregister WORD l;
X{
X	register WORD pad;
X
X	Bconws(s);
X	if((pad = l - strlen(s)) <= 0)
X		return;
X	for(; pad > 0; pad--)
X		Bconout(2, ' ');
X}
X
X
X/*
X * Return the nth entry in the phone directory
X *
X */
XDIR nth(n)
Xregister WORD n;
X{
X	register WORD i;
X	register DIR dir;
X	
X	for(i = 0, dir = directory; (dir != (DIR)NULL) & (i < n);
X	    i++, dir = dir->next)
X	    /* Skip */;
X	return(dir);
X}
X
X/*
X * Add a entry in the phonebook
X */
Xaddir()
X{
X	register DIR dir;
X	register char *s;
X	extern char *malloc(), *preadl();
X	
X	/* If a directory file already exists add, else read or create */
X	if(rflag == 0)
X	{
X		switch(readdir())
X		{
X		    case -3:
X			/* Doesnt exist, but we will create it when we
X			   write out the directory */
X			rflag = 1;
X			break;
X			
X		    case 0:
X		    case -2:
X		    case -1:
X			hit_key();
X			return;
X			
X		    default:
X			rflag = 1;
X			break;
X		}
X	}
X	
X	/* Allocate space for the new entry */
X	if((dir = (DIR)malloc(sizeof(struct _dir))) == (DIR)NULL)
X	{
X		Bconws("Out of Memory\r\n");
X		hit_key();
X		return;
X	}
X	
X	if((dir->name = malloc(12)) == (char *)NULL)
X	{
X		/* Out of memory */
X		Bconws("Out of Memory\r\n");
X		hit_key();
X		return;
X	}
X
X	if((dir->number = malloc(25)) == (char *)NULL)
X	{
X		/* Out of memory */
X		Bconws("Out of Memory\r\n");
X		hit_key();
X		return;
X	}
X
X		
X	/* Get the entry */
X	
X	do {
X		Bconws("Name: ");
X		s = preadl();
X	} while(s == (char *)NULL);
X	
X	strncpy(dir->name,s,11);
X	
X	do {
X		Bconws("Number: ");
X		s = preadl();
X	} while(s == (char *)NULL);
X	
X	strncpy(dir->number,s,24);
X	
X	do {
X		Bconws("Baud Rate: ");
X		s = preadl();
X	} while((s == (char *)NULL) || ((dir->baud = tobaud(s)) == -1));
X	
X	dir->next = (DIR)NULL;
X	
X	if(directory == (DIR)NULL)
X	    directory = dir;
X	else
X	    lastdir->next = dir;
X
X	lastdir = dir;
X	dchanged = 1;
X	ndir++;
X}
X
X
X
X/*
X * Convert a string to a baud rate
X * return int or -1 if invalid
X */
XWORD tobaud(s)
Xregister char *s;
X{
X	register WORD i;
X	
X	for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
X	{
X		if(strcmp(vbauds[i].sbaud,s) == 0)
X		    return vbauds[i].ibaud;
X	}
X
X	Bconws(s);
X	Bconws(": Invalid Baud Rate\r\nValid Baud Rates are:\r\n");
X	for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
X	{
X		Bconout(2, '\t');
X		if((i != 0) && (vbauds[i].ibaud != vbauds[i-1].ibaud))
X		{
X			Bconws(vbauds[i].sbaud);
X			Bconws("\r\n");
X		}
X	}
X		
X	return -1;
X}
X
X/*
X * Dial a number 
X */
Xdial()
X{
X	register WORD n;
X	register DIR dir;
X	extern DIR nth();
X	
X	/* Has the directory been read so far */
X	if(rflag == 0)
X	{
X		/* Go read it */
X		switch(readdir())
X		{
X		    case -1:
X		    case -2:
X		    case -3:
X		    case 0:
X			rflag = 0;
X			hit_key();
X			his_screen();
X			return;
X		    default:
X			break;
X		}
X	}
X	
X	if((n = showdir()) == -1)
X	{
X		/* Cancelled */
X		hit_key();
X		his_screen();
X		return;
X	}
X	
X	his_screen();
X	dir = nth(n);
X	if(dir->baud != speed)
X	{
X		speed = dir->baud;
X		Baudrate = jbaud(speed);
X		Rsconf(speed, -1, -1, -1, -1, -1);
X		sendchar('\r');
X		flushinput();
X	}
X	write_modem(PREDIAL, strlen(PREDIAL));
X	write_modem(dir->number,strlen(dir->number));
X	sendchar('\r');
X}
X
X
X/*
X * Re-dial the previous number
X *
X *	Does it cheaply, by sending the modem its Re-dial
X *	sequence, instead of remembering the last number dialed etc.
X *
X */
Xredial()
X{
X	his_screen();
X	write_modem(REDIAL ,strlen(REDIAL));
X}
X
X
X/*
X * Open a phone directory 
X *
X */
Xopendir()
X{
X	/* if one is open, save it if changed, then deallocate memory
X 	 * and then open a new directory
X	 */
X	if(rflag)
X	{
X		if(dchanged)
X		{
X			if(writedir() == 1)
X			{
X				hit_key();
X				return;
X			}
X			dchanged = 0;
X		}
X		freedir(directory);
X	}
X	
X	if(readdir() <= 0)
X	{
X		hit_key();
X		return;
X	}
X}
X
X/*
X * Delete an entry.
X */
Xdelentry()
X{
X	register DIR dir, del;
X	register WORD n;
X	extern DIR nth();
X	
X	if(rflag == 0)
X	{
X		Bconws("Nothing to delete\r\n");
X		hit_key();
X		return;
X	}
X	
X	if((n = showdir()) == -1)
X	{
X		/* Cancelled */
X		hit_key();
X		return;
X	}
X	
X	if(ndir == 1)
X	{
X		del = directory;
X		directory = (DIR)NULL;
X		lastdir = (DIR)NULL;
X	}
X	else
X	{
X		if(n == 0)
X		{
X			del = directory;
X			dir = directory->next;
X			directory = dir;
X		}
X		else
X		{
X			dir = nth(n-1);
X			del = dir->next;
X			dir->next = del->next;
X			if(lastdir == del)
X			    lastdir = dir;
X		}
X	}
X	
X	free(del->name);
X	free(del->number);
X	free(del);
X	ndir--;
X	dchanged = 1;
X	
X}
X
X	
X/*
X * Phone services - top level
X *
X */
Xphone()
X{
X	register LONG conin;
X	
X	while(1)
X	{
X		clear_screen();
X		mvto(2,32);
X		inv();
X		Bconws("Phone  Services");
X		normal();
X
X		mvto(5,0);
X		
X		if(rflag)
X		{
X			Bconws("\tThe Phone Directory \"");
X			Bconws(dirfile);
X			Bconws("\" containing ");
X			printf("%d", ndir); fflush(stdout);
X			Bconws(" Entry(s) is Currently Open.\r\n\n");
X		}
X		else
X		    Bconws("\tNo Phone Directory is Currently Open.\r\n\n");
X		
X		
X		/* Put up menu */
X		Bconws("\r\n\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("Undo");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to exit the emulator.\r\n");
X		
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("d");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to dial a number.\r\n");
X		
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("a");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to add an entry to the phone directory.\r\n");
X		
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("D");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to delete an entry from the phone directory.\r\n");
X		
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("o");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to open another phone directory.\r\n");
X
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("r");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to re-dial last number.\r\n");
X		
X		Bconws("\t");
X		EscSeq('p');		/* reverse video */
X		Bconws("Return");
X		EscSeq('q');		/* quit reverse video */
X		Bconws(" to return to the emulator.\r\n\n\n\n");
X		
X		/* get response */
X		conin = Bconin(2);
X		
X		if ((conin & 0x00FF0000L) == 0x610000L)
X		{
X			/* He hit <UNDO> */
X			his_screen();
X			ResetIoBuf();
X			finish();
X		}
X		
X		switch((WORD)(conin & 0x7f))
X		{
X		    case 'd':
X			/* Dial a number */
X			dial();
X			return;
X			
X		    case 'D':
X			/* Delete an entry */
X			delentry();
X			break;
X			
X		    case 'a':
X			/* Add an entry */
X			addir();
X			break;
X			
X		    case 'o':
X			/* Open another phone directory */
X			opendir();
X			break;
X			
X
X		    case 'r':
X			/* Re-Dial # */
X			redial();
X			return;
X			
X		    case '\r':
X			his_screen();
X			return;
X			
X		    default:
X			break;
X		}
X		
X	}
X	
X}
X
X/*
X * Convert a baud rate to its int
X * return int or -1 if invalid
X */
XWORD jbaud(bd)
Xregister WORD bd;
X{
X	register WORD i;
X	
X	for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
X	{
X		if(vbauds[i].ibaud == bd)
X		    return vbauds[i].jbaud;
X	}
X	return -1;
X}
X
Xstatic char scrth[80];
X/*
X * Read a line from Standard Input and return a 
X * NULL terminated pointer to it
X */
Xchar *preadl()
X{
X	/* Use the scrth bufr for storage */
X	scrth[0] = 80;
X	Cconrs(scrth);
X	Bconws("\r\n");
X	if(scrth[1] == 0)
X	{
X		/* User Cancelled */
X		Bconws("Cancelled\r\n");
X		return((char *)NULL);
X	}
X	/* Terminate string that starts at scrth[2] */
X	scrth[scrth[1]+2] = '\0';
X	return(&scrth[2]);
X}	
X
X#endif /* PHONES */
X#endif /* STANDALONE */
X
X/* -eof - */
SHAR_EOF
chmod 0600 PHONE.C || echo "restore of PHONE.C fails"
echo "x - extracting RZ.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > RZ.C &&
X/*
X *			    ACKNOWLEDGEMENTS
X *
X *	ZMDM was derived from rz/sz for Unix  posted by 
X *	Chuck Forsberg (...!tektronix!reed!omen!caf ). We
X *	thank him for his excellent code, and for giving
X *	us permission to use and distribute his code and
X *	documentation.
X *
X *	Atari St version by:
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#define RVERSION "rz 1.14 01-15-87"
X#define RSTVERSION "rz 1.01 03-07-87"
X#define OS	"Unix V7/BSD"
X
X/* #define RDEBUG */			/* a lot of debugging garb */
X
X/*
X *	ATARI ST series implementation notes:
X *
X *		- the following command line options were removed as they
X *		  were either  not applicable to the ST environment or
X *		  were not deemed reasonable (by me - ofcourse).
X *			1	Not Applicable here as we have a seperate
X *				serial port.
X *			7	In this day and age? Forget it, get another m/c.
X *			a/b	Ascii/Binary - the receive mode (if not
X *				over-ridden by the sender) is automatically
X *				selected depending on the extention given
X *				in the incoming file name. This idea was
X *				present in earlier rz/sz, i wonder why such
X *				a convenient feature was dropped (Chuck ??).
X *				This feature is relevant to ZMODEM only in rz,
X *				as the sender determines the file mode in
X *				XMODEM/YMODEM transfers.
X *		        B	Note that `B' has a special meaning.
X *				Specifying -B will force override to
X *				binary mode for each incoming file. Useful
X * 				when doing St-to-St transfers.
X *			D	There is no /dev/null on the ST's
X *			u	not applicable to TOS. Upper and lower
X *				case file names are the same. All the
X *				applicable routines like uncap() and
X *				IsAnyLower() were zapped.
X *
X *		- The	[-][v]rzCOMMAND style of invocation was dropped
X *		  as there is no good way to do pipes without the 
X *		  microRtx kernal. All references to Pipe and popen()
X *		  were zapped.
X *		- Verbose is always set to 2 by automatically, as we know that
X *		  stdout != stderr. This can be overridden
X *		  by specifying -q to ensure that Verbose = 0
X *		- The idea of a PUBDIR and Restricted paths in the origonal
X *		  code  was dropped totally as it is not applicable
X *		  to the single owner ST environment. 1 man 1 machine.
X *		- CRCTABLE is default always, hey we have plenty of memory!.
X *		- LOGFILE renamed to 'rzlog/szlog' as we don't always have
X *		  a meaningful environment to pick up TMPDIR from (like when
X *		  running from the desktop).
X *	        - When a subdirectory in an incoming path name is not
X *		  present it is created.
X *		- The file mode transmitted is 0S00 where S is derived from
X *		  the Read/Write attribute of the file on the ST
X *		- When a file mode is received, only the owner bits are
X *		  are checked. If it was read only (r--) on the Unix sytem
X *		  then it is given read only attribute on the ST, read-write
X *		  otherwise.
X *		- Of course all the I/O was completely redone on the ST.
X *		- You will find two versions of VARARGS routines like log,
X *		  one that takes int args, and the other that takes long
X *		  (address) args, since sizeof(int) != sizeof(long)
X *		  and sizeof(int) != sizeof(pointer) on the ST.
X *
X *	ST v1.01
X *	 added support for 32 bit CRC's for Zmodem ++jrb
X *
X *	ST v1.2
X *	 added -B ++jrb
X *	 added all the recursive stuff
X *	 added remote
X */
X		
X/*% cc -DNFGVMIN -DCRCTABLE -K -O % -o rz; size rz
X *
X * rz.c By Chuck Forsberg
X *
X *	cc -O rz.c -o rz		USG (3.0) Unix
X * 	cc -O -DV7  rz.c -o rz		Unix V7, BSD 2.8 - 4.3
X *
X *	ln rz rb			For either system
X *
X *	ln rz /usr/bin/rzrmail		For remote mail.  Make this the
X *					login shell. rzrmail then calls
X *					rmail(1) to deliver mail.
X *
X *		define CRCTABLE to use table driven CRC
X *
X *  Unix is a trademark of Western Electric Company
X *
X * A program for Unix to receive files and commands from computers running
X *  Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
X *  rz uses Unix buffered input to reduce wasted CPU time.
X *
X * Iff the program is invoked by rzCOMMAND, output is piped to 
X * "COMMAND filename"
X *
X *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
X *  read(2) the same way as Unix. ONEREAD must be defined to force one
X *  character reads for these systems. Added 7-01-84 CAF
X *
X *  Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF 
X *
X *  NFGVMIN Added 1-13-85 CAF for PC-AT Xenix systems where c_cc[VMIN]
X *  doesn't seem to work (even though it compiles without error!).
X *
X *  USG UNIX (3.0) ioctl conventions courtesy  Jeff Martin
X */
X
X
X#include "zmdm.h"
X#include "common.h"
X#include "zmodem.h"
X
Xstatic unsigned long SaveIntr;
X
X#ifndef Vsync 			/* Atari forgot these in osbind.h */
X#define Vsync()	xbios(37)
X#endif
X
X#ifndef Supexec
X		/* Some versions of osbind don't define Supexec */
X#define Supexec(X) xbios(38,X)
X#endif
X
X#if (MWC || MANX)
Xextern FILE  *fopen();
X#else
Xextern FILE  *fopen(), *fopenb();
X#endif
X
X#ifndef STANDALONE
X#define RETURN return
X#else
Xint bibis() {} /* dummy */
X#endif 
X
Xstatic long start_time;
X
X/* called by simulated signal interrupt or terminate to clean things up */
Xbibi(n)
Xint n;
X{
X
X	if (Zmodem)
X		zmputs(Attn);
X	canit(); mode(0);
X	fprintf(STDERR, "\r\nrz: caught signal %d; exiting", n);
X	if (fout != -1)
X	{
X		if (stfclose(fout) != 0)
X		{
X			fprintf(STDERR, "\r\nfile close ERROR\n");
X		}
X		fout = (-1);
X
X	}
X
X#ifdef RDEBUG
X	if (logf != (FILE *)NULL)
X		fclose(logf);
X#endif
X	aexit(128+n);
X}
X
X#ifdef STANDALONE
Xmain(argc, argv)
X#else
Xdorz(argc, argv)
X#endif /* STANDALONE */
Xint argc;
Xchar **argv;
X{
X	register char *cp;
X	register int npats;
X	char **patts;
X	int exitcode;
X
X#ifdef STANDALONE
X#ifdef MWC
X	extern char *lmalloc();
X#endif
X
X	/* Set up Dta */
X	Fsetdta(&statbuf);
X
X	/* Get screen rez */
X	rez = Getrez();
X	drv_map = Drvmap();
X
X#if (MWC || MANX)
X#ifndef DYNABUF
X#ifdef MWC
X	if((bufr = (unsigned char *)lmalloc((unsigned long)BBUFSIZ))
X					 == (unsigned char *)NULL)
X#else
X	if((bufr = (unsigned char *)Malloc((unsigned long)BBUFSIZ))
X					 == (unsigned char *)NULL)
X#endif
X#else
X	if((bufr = dalloc()) == (unsigned char *)NULL)
X#endif /* DYNABUF */
X	{
X#ifdef REMOTE
X		Bauxws("Sorry, could not allocate enough memory\r\n");
X#else
X		Bconws("Sorry, could not allocate enough memory\r\n");
X#endif
X
X		Pterm(4);
X	}
X#else /* MWC || MANX */
X#ifdef DYNABUF
X	if((bufr = dalloc()) == (unsigned char *)NULL)
X	{
X#ifdef REMOTE
X		Bauxws("Sorry, could not allocate enough memory\r\n");
X#else
X		Bconws("Sorry, could not allocate enough memory\r\n");
X#endif
X		Pterm(5);
X	}
X#endif /* DYNABUF */
X#endif /* MWC || MANX */
X
X#ifndef REMOTE
X	STDERR = stderr;
X#else
X#ifndef DLIBS
X	if((STDERR = fopen("aux:", "rw")) == (FILE *)NULL)
X	{
X		Bauxws("Could not Open Aux Stream for Stderr\r\n");
X		finish();
X	}
X	setbuf(STDERR, (char *)NULL);
X#else
X	STDERR = stdaux;
X#endif /* DLIBS */
X	
X#endif /* REMOTE */
X
X	{
X		int speed;
X		speed = getbaud();
X		Baudrate = BAUD_RATE(speed);
X		SetIoBuf();
X		Rsconf(speed, 0,-1,-1,-1,-1);
X		Vsync(); Vsync();
X	}
X
X#endif /* STANDALONE */
X
X	SendType = 0;
X	Rxtimeout = 100;
X	exitcode = 0;
X
X	initz();
X
X#ifndef STANDALONE
X	chkinvok(argv[0]); 	/* if called as  'rb' set flag */
X#else
X	Progname = "rz";
X#endif
X
X	npats = 0;
X	SaveIntr = Setexc(0x0102, -1L);
X	BusErr   = Setexc(2, -1L);
X	AddrErr  = Setexc(3, -1L);
X	vdebug = 0;
X
X	while (--argc)
X	{
X		cp = *++argv;
X		if (*cp == '-')
X		{
X			while( *++cp)
X			{
X				switch(*cp)
X				{
X				case '+':
X					Lzmanag = ZMAPND; break;
X				case 'B':
X					ForceBinary=TRUE; break;
X				case 'c':
X					Crcflg=TRUE; break;
X				case 'p':
X					Lzmanag = ZMPROT;  break;
X				case 'q':
X					Quiet=TRUE; Verbose=0; break;
X				case 't':
X					if (--argc < 1) {
X						rusage();
X						RETURN(1);
X					}
X					Rxtimeout = atoi(*++argv);
X					if (Rxtimeout<10 || Rxtimeout>1000)
X					{
X						rusage();
X						RETURN(1);
X					}
X					break;
X				case 'v':
X					++Verbose; break;
X				default:
X					rusage();
X					RETURN(1);
X				}
X			}
X		}
X		else if ( !npats && argc>0)
X		{
X			if (argv[0][0])
X			{
X				npats=argc;
X				patts=argv;
X			}
X		}
X	}
X
X	if (npats > 1)
X	{
X		rusage();
X		RETURN(1);
X	}
X
X#ifdef RDEBUG
X	if (Verbose > 2)
X	{
X		if ((logf = fopen(RLOGFILE, "a"))== (FILE *)NULL)
X		{
X			fprintf(STDERR, "Can't open log file %s\n",RLOGFILE);
X			RETURN(0200);
X		}
X		fprintf(logf, "Progname=%s\n", Progname);
X		vdebug = 1;
X	}
X#endif
X
X	if ( !Quiet)
X	{
X		if (Verbose == 0)
X			Verbose = 2;
X	}
X
X	Setexc(0x0102, bibi);
X
X	Setexc(2, buserr);
X	Setexc(3, addrerr);
X
X	if((exitcode = setjmp(abrtjmp)))
X	{
X		/* on Contrl-C */
X		canit();
X		Setexc(2, BusErr);
X		Setexc(3, AddrErr);
X		Setexc(0x0102, SaveIntr);
X		RETURN(exitcode);
X	}
X	
X	if(setjmp(busjmp))
X	{
X		/* On a bus error - instead of 2 bombs */
X		fprintf(STDERR,"\r\nFATAL: Bus Error\n\n");
X#ifdef RDEBUG
X		if(logf != (FILE *)NULL)
X			fclose(logf);
X#endif
X		if(fout != -1)
X		{
X			if (stfclose(fout) != 0)
X			{
X				fprintf(STDERR, "\r\nfile close ERROR\n");
X			}
X			fout = (-1);
X		}
X		canit();
X		Setexc(2, BusErr);
X		Setexc(3, AddrErr);
X		Setexc(0x0102, SaveIntr);
X
X		RETURN(2);
X	}
X
X	if(setjmp(addrjmp))
X	{
X		/* On address error - instead of 3 bombs */
X		fprintf(STDERR,"\r\nFATAL: Address Error\n\n");
X#ifdef RDEBUG
X		if(logf != (FILE *)NULL)
X			fclose(logf);
X#endif
X		if(fout != -1)
X		{
X			if (stfclose(fout) != 0)
X			{
X				fprintf(STDERR, "\r\nfile close ERROR\n");
X			}
X			fout = (-1);
X		}
X		canit();
X		Setexc(2, BusErr);
X		Setexc(3, AddrErr);
X		Setexc(0x0102, SaveIntr);
X
X		RETURN(3);
X	}
X
X	mode(1);
X
X	if (wcreceive(npats, patts)==ERROR)
X	{
X		exitcode=0200;
X		canit();
X	}
X
X	mode(0);
X	if (exitcode && !Zmodem)	/* bellow again with all thy might. */
X		canit();
X
X#ifdef RDEBUG
X	if(logf != (FILE *)NULL)
X		fclose(logf);
X#endif
X
X	if(fout != -1)
X	{
X		if (stfclose(fout) != 0)
X		{
X			fprintf(STDERR, "\r\nfile close ERROR\n");
X		}
X		fout = (-1);
X	}
X	Setexc(2, BusErr);
X	Setexc(3, AddrErr);
X	Setexc(0x0102, SaveIntr);
X
X 	RETURN(exitcode); 
X}
X
X#ifdef STANDALONE
XRETURN(n)
Xint n;
X{
X	ResetIoBuf();
X#if (MWC || MANX)
X#ifndef DYNABUF
X	free(bufr);
X#else
X	Mfree(bufr);
X#endif
X#else
X#ifdef DYNABUF
X	Mfree(bufr);
X#endif
X#endif
X
X	exit(n);
X}
X#endif /* STANDALONE */
X
Xrusage()
X{
X	fprintf(STDERR,
X		"%s for %s by ST Enthusiasts at Case Western Reserve University\n",
X	  	RSTVERSION, STOS);
X	fprintf(STDERR, "\tBased on %s for %s by Chuck Forsberg\n\n",
X		RVERSION, OS);
X
X	fprintf(STDERR,"Usage:	rz [-Bpqtv]		(ZMODEM Batch)\n");
X	fprintf(STDERR,"or	rb [-qtv]		(YMODEM Batch)\n");
X	fprintf(STDERR,"or	rz [-cqtv] file	        (XMODEM or XMODEM-1k)\n");
X	fprintf(STDERR,"	  -B Force Binary Mode transfers\n");
X	fprintf(STDERR,"	  -v Verbose more v's give more info\n");
X	fprintf(STDERR,"          -q Quiet suppresses verbosity\n");
X	fprintf(STDERR,"	  -t TIM Change timeout to TIM tenths of seconds\n");
X	fprintf(STDERR,"	  -c Use 16 bit CRC	(XMODEM)\n");
X	fprintf(STDERR,"	  -p Protect existing dest. file by skipping\n");
SHAR_EOF
echo "End of part 3"
echo "File RZ.C is continued in part 4"
echo "4" > s2_seq_.tmp
exit 0