From pa.dec.com!decwrl!uunet!sparky!kent Sun Aug 11 15:43:22 PDT 1991
Article: 2585 of comp.sources.misc
Newsgroups: comp.sources.misc
Path: pa.dec.com!decwrl!uunet!sparky!kent
From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Subject:  v21i075:  ecu - ECU async comm package rev 3.10, Part23/37
Message-ID: <1991Aug4.163038.18661@sparky.IMD.Sterling.COM>
X-Md4-Signature: a98826c8f621e248594b54506f6f783c
Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield)
Organization: Sterling Software, IMD
References: <csm-v21i053=ecu.215539@sparky.imd.sterling.com>
Date: Sun, 4 Aug 1991 16:30:38 GMT
Approved: kent@sparky.imd.sterling.com
Lines: 2254

Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Posting-number: Volume 21, Issue 75
Archive-name: ecu/part23
Environment: SCO, XENIX, ISC
Supersedes: ecu3: Volume 16, Issue 25-59

---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is ecu310.23 (part 23 of ecu310)
# do not concatenate these parts, unpack them in order with /bin/sh
# file z/zcurses.c continued
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 23; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping z/zcurses.c'
else
echo 'x - continuing file z/zcurses.c'
sed 's/^X//' << 'SHAR_EOF' >> 'z/zcurses.c' &&
X
X	if(!final && (current_seconds < (last_report + 5L)))
X		return;
X	last_report = current_seconds;
X
X	elapsed_seconds = current_seconds - this_file_start_seconds;
X
X	if(count && (elapsed_seconds > 0) &&
X		zcurses_baud_rate)
X	{
X		rate = (float)count / (float)elapsed_seconds;
X		if(zcurses_baud_rate)
X			eff  = 100.0 * (rate / ((float)zcurses_baud_rate / 10.0));
X	}
X
X	if(rate > 0.01)
X	{
X		sprintf(s128,"XFERINFO %s rate ~= %.0f ch/sec (%.0lf%%)",
X			text,rate,(eff > 0.5) ? eff : 0.0);
X#if defined(WHT)
X		if(final)
X			ecu_log_event(getppid(),s128);
X#endif
X	}
X
X	if(!no_curses && s128[0])
X		report_top_line(s128 + 9);
X
X}	/* end of report_file_xfer_rate */
X
X/*+-------------------------------------------------------------------------
X	report_rxpos(rxpos) row 3 col 19 len 8
X--------------------------------------------------------------------------*/
Xvoid
Xreport_rxpos(rxpos)
Xlong rxpos;
X{
Xchar tmp[16];
X#if defined(M_SYS5)
Xchar refr;
X
X	if(no_curses)
X	{
X		return;
X	}
X
X	if(rdchk(0))
X	{
X		read(0,&refr,1);
X		if(refr == 0x0C || refr == 0x012)	/* ^L or ^R */
X		{
X			write(2,"\033[2J",4);
X			nap((long)60);
X			touchwin(stdscr);
X			wrefresh(stdscr);
X			touchwin(win);
X			wrefresh(win);
X		}
X	}
X#endif
X
X	if((rxpos > 99999999L) || (rxpos < 0L))
X		return;
X
X	sprintf(tmp,"%-8lu",rxpos);
X	wmove(win,3,19);
X	waddstr(win,tmp);
X	report_file_xfer_rate("transfer",rxpos,0);
X	report_rx_tx_count();	/* which will do a refresh */
X
X}	/* end of report_rxpos */
X
X/*+-------------------------------------------------------------------------
X	report_txpos(txpos)
X--------------------------------------------------------------------------*/
Xvoid
Xreport_txpos(txpos)
Xlong txpos;
X{
X	if(no_curses)
X	{
X		return;
X	}
X
X	report_rxpos(txpos);
X}	/* end of report_txpos */
X
X/*+-------------------------------------------------------------------------
X	report_error_count()
X	DOES NOT PERFORM A REFRESH CYCLE
X
X  this file: row 10 col 22 len 3
X  total:     row 10 col 33 len 4
X  skipped:   row 10 col 53 len 3
X--------------------------------------------------------------------------*/
Xreport_error_count()
X{
X	char tmp[16];
X
X	if(no_curses)
X	{
X		return;
X	}
X
X	wmove(win,10,22);
X	sprintf(tmp,"%-3d",this_file_errors);
X	if(this_file_errors)
X		wstandout(win);
X	waddstr(win,tmp);
X	if(this_file_errors)
X		wstandend(win);
X
X	wmove(win,10,33);
X	sprintf(tmp,"%-4d",total_errors);
X	if(total_errors)
X		wstandout(win);
X	waddstr(win,tmp);
X	if(total_errors)
X		wstandend(win);
X
X	wmove(win,10,53);
X	sprintf(tmp,"%-3d",skip_count);
X	waddstr(win,tmp);
X	wrefresh(win);
X
X}	/* end of report_error_count */
X
X/*+-------------------------------------------------------------------------
X	report_last_txhdr(rptstr,error_flag)
X	5,7,22
X--------------------------------------------------------------------------*/
Xvoid
Xreport_last_txhdr(rptstr,error_flag)
Xregister char *rptstr;
Xint error_flag;
X{
Xchar s24[24];
X
X	if(log_packets)
X	{
X		write(log_packets,"tx:   ",6);
X		write(log_packets,rptstr,strlen(rptstr));
X		write(log_packets,"\n",1);
X	}
X
X	if(no_curses)
X	{
X		if(error_flag)
X		{
X			no_curses_newline();
X			no_curses_pos = printf("%s ",rptstr);
X			++this_file_errors;
X			++total_errors;
X		}
X		return;
X	}
X
X	if(strlen(rptstr) > 22)
X	{
X		strncpy(s24,rptstr,22);
X		s24[23] = 0;
X		rptstr = s24;
X	}
X	clear_area(win,5,7,22);
X	waddstr(win,rptstr);
X
X	if(error_flag)
X	{
X		++this_file_errors;
X		++total_errors;
X		report_error_count();
X	}
X
X}	/* end of report_last_txhdr */
X
X/*+-------------------------------------------------------------------------
X	report_last_rxhdr(rptstr,error_flag)
X	5,35,22
X--------------------------------------------------------------------------*/
Xvoid
Xreport_last_rxhdr(rptstr,error_flag)
Xregister char *rptstr;
Xint error_flag;
X{
Xchar s24[24];
Xextern int log_packets;
X
X	if(log_packets)
X	{
X		write(log_packets,"rx:   ",6);
X		write(log_packets,rptstr,strlen(rptstr));
X		write(log_packets,"\n",1);
X	}
X
X	if(no_curses)
X	{
X		if(error_flag)
X		{
X			no_curses_newline();
X			no_curses_pos = printf("%s ",rptstr);
X			++this_file_errors;
X			++total_errors;
X		}
X		return;
X	}
X
X	if(strlen(rptstr) > 22)
X	{
X		strncpy(s24,rptstr,22);
X		s24[23] = 0;
X		rptstr = s24;
X	}
X	clear_area(win,5,35,22);
X	waddstr(win,rptstr);
X
X	if(error_flag)
X	{
X		++this_file_errors;
X		++total_errors;
X		report_error_count();
X	}
X	report_window();
X
X}	/* end of report_last_rxhdr */
X
X/*+-------------------------------------------------------------------------
X	report_str(rptstr,error_flag) row 11/12 col 3 len 55
X
X  error_flag == 0 for status/progress message
X             == 1 for bump error count, unless rptstr is null
X                  in which case, merely clear error string area
X             == 2 write string on bottom line (not an error)
X             == 3 write string on transaction line (not an error)
X             == -1 use error line but do not bump error count
X--------------------------------------------------------------------------*/
Xvoid
Xreport_str(rptstr,error_flag)
Xregister char *rptstr;
Xint error_flag;
X{
Xchar s60[60];
Xextern int log_packets;
X
X	if(log_packets)
X	{
X		sprintf(s60,"rpt %d:",error_flag);
X		write(log_packets,s60,strlen(s60));
X		write(log_packets,rptstr,strlen(rptstr));
X		write(log_packets,"\n",1);
X	}
X
X	if(no_curses)
X	{
X		if(!strlen(rptstr))
X			return;
X		switch(error_flag)
X		{
X			case 0:
X				break;
X			case 1:
X				this_file_errors++;
X				total_errors++;
X			case -1:
X			case 2:
X			case 3:
X				no_curses_newline();
X				no_curses_pos = printf("%s ",rptstr);
X				fflush(stdout);
X		}
X		return;
X	}
X
X	if(strlen(rptstr) > 55)
X	{
X		strncpy(s60,rptstr,55);
X		s60[55] = 0;
X		rptstr = s60;
X	}
X
X	switch(error_flag)
X	{
X		case 0:
X			clear_area(win,12,3,55);
X			break;
X		case 1:
X			this_file_errors++;
X			total_errors++;
X			report_error_count();
X		case -1:
X			clear_area(win,11,3,55);
X			break;
X		case 2:
X			clear_area(win,13,3,55);
X			break;
X		case 3:
X			clear_area(win,4,3,55);
X			break;
X	}
X
X	waddstr(win,rptstr);
X	wrefresh(win);
X
X}	/* end of report_str */
X
X/*+-------------------------------------------------------------------------
X	report_transaction()
X--------------------------------------------------------------------------*/
Xvoid
Xreport_transaction(str)
Xchar *str;
X{
X	report_str(str,3);
X}	/* end of report_transaction */
X
X/*+-------------------------------------------------------------------------
X	report_file_open_tod() -- time of start of this file
X
X  this file open time: row 8 col 41 length 8
X--------------------------------------------------------------------------*/
Xvoid
Xreport_file_open_tod()
X{
X	if(no_curses)
X		return;
X	clear_area(win,8,41,8);
X	waddstr(win,get_tod(1,(char *)0));
X	wrefresh(win);
X}	/* end of report_file_open_tod */
X
X/*+-------------------------------------------------------------------------
X	report_file_open_mode(file_mode)
X  mode map: row 4 col 46 len 10
X--------------------------------------------------------------------------*/
Xreport_file_open_mode(file_mode)
Xunsigned short file_mode;
X{
X	if(no_curses)
X		return;
X	clear_area(win,3,46,10);
X	waddstr(win,mode_map(file_mode,(char *)0));
X	wrefresh(win);
X}	/* end of report_file_open_mode */
X
X/*+-------------------------------------------------------------------------
X	report_file_open_length(long_length)
X  length:   row 3 col 36 len  8
X--------------------------------------------------------------------------*/
Xreport_file_open_length(length)
Xlong length;
X{
X	if(no_curses)
X		return;
X	clear_area(win,3,36,8);
X	if(length <= 0)
X		waddstr(win,"unknown");
X	else
X	{
X		sprintf(s128,"%-8lu",length);
X		waddstr(win,s128);
X	}
X	wrefresh(win);
X}	/* end of report_file_open_length */
X
X/*+-------------------------------------------------------------------------
X	report_file_send_open(filename,filestat)
X
X  filename: row 2 col 20 len 38
X  number:   row 2 col 8 len 3
X  length:   row 3 col 36 len  8
X  mode:     row 3 col 46 len 10
X  time of start of this file: row 4 col 47 length 8 hh:mm:ss
X--------------------------------------------------------------------------*/
Xvoid
Xreport_file_send_open(filename,filestat)
Xchar *filename;
Xstruct stat *filestat;
X{
Xchar s50[50];
Xregister char *cptr = filename;
X
X	if(log_packets)
X	{
X		write(log_packets,"file: ",6);
X		write(log_packets,filename,strlen(filename));
X		write(log_packets,"\n",1);
X	}
X
X	this_file_start_seconds = time((long *)0);
X	this_file_xfer_count = 0;
X
X	if(no_curses)
X	{
X		no_curses_newline();
X		no_curses_pos = printf("Sending '%s' ",filename);
X		fflush(stdout);
X		return;
X	}
X
X	/* number */
X	clear_area(win,2,8,3);
X	sprintf(s50,"%-3d",Filcnt);
X	waddstr(win,s50);
X
X	/* filename */
X	if(strlen(filename) > 38)
X	{
X		strncpy(s50,filename,38);
X		s50[39] = 0;
X		cptr = s50;
X	}
X	clear_area(win,2,20,38);
X	waddstr(win,cptr);
X
X	/* length */
X	report_file_open_length(filestat->st_size);
X
X	/* mode */
X	report_file_open_mode(filestat->st_mode);
X
X	/* time of start of this file */
X	report_file_open_tod();
X
X	this_file_errors = 0;
X	report_error_count();
X}	/* end of report_file_send_open */
X
X/*+-------------------------------------------------------------------------
X	report_file_rcv_started(filename,length,last_mod_time,file_mode)
X
X  filenumber: row 2 col  8 len  3
X              row 2 col 12 len  7 clear "of ###"
X  filename:   row 2 col 20 len 38
X--------------------------------------------------------------------------*/
Xreport_file_rcv_started(filename,length,last_mod_time,file_mode)
Xchar *filename;
Xlong length;					/* if < 0, "UNKNOWN" */
Xlong last_mod_time;			/* not currently displayed */
Xunsigned short file_mode;		/* UNIX file modifier or zero */
X{
Xregister char *cptr;
Xchar s50[50];
X
X	if(log_packets)
X	{
X		write(log_packets,"file: ",6);
X		write(log_packets,filename,strlen(filename));
X		write(log_packets,"\n",1);
X	}
X
X	this_file_start_seconds = time((long *)0);
X	this_file_xfer_count = 0;
X
X	if(no_curses)
X	{
X		no_curses_newline();
X		no_curses_pos = printf("Receiving '%s' ",filename) - 2;
X		fflush(stdout);
X		return;
X	}
X
X	/* filename */
X	if(strlen(filename) > 38)
X	{
X		strncpy(s50,filename,38);
X		s50[39] = 0;
X		cptr = s50;
X	}
X	else
X		cptr = filename;
X
X	clear_area(win,2,20,38);
X	waddstr(win,cptr);
X
X	/* file number */
X	clear_area(win,2,8,3);
X	sprintf(s50,"%-3d",Filcnt);	/* rz uses as file number 1-n */
X	waddstr(win,s50);
X
X/* if remote sender provides a file count, display it */
X	if(npats)
X	{
X		clear_area(win,2,12,7);	/* clear "of ###" */
X		sprintf(s50,"of %3d:",npats);
X		waddstr(win,s50);
X	}
X
X	/* length */
X	report_file_open_length(length);
X
X	/* mode */
X	report_file_open_mode(file_mode);
X
X	/* time of start of this file */
X	report_file_open_tod();
X
X	this_file_errors = 0;
X	report_error_count();
X}	/* end of report_file_rcv_started */
X
X
X/*+-------------------------------------------------------------------------
X	report_file_close(skipped)
X--------------------------------------------------------------------------*/
Xvoid report_file_close(skipped)
Xint skipped;
X{
X
X	if(no_curses)
X	{
X		no_curses_newline();
X		no_curses_pos +=
X			printf("Transfer time was %s",get_elapsed_time(elapsed_seconds));
X		no_curses_newline();
X		if(s128[0])
X		{
X			no_curses_pos += strlen(s128 + 9);
X			fputs(s128 + 9,stdout);
X			no_curses_newline();
X		}
X		if(this_file_errors)
X		{
X			no_curses_pos +=
X				printf("Errors for this file were %d",this_file_errors);
X			no_curses_newline();
X		}
X		return;
X	}
X
X	if(show_window)
X	{
X		clear_area(win,9,50,8);
X		waddstr(win,"+0");
X		Txpos = 0;
X		Rxpos = 0;
X	}
X
X	report_str("End of file",0);
X	if(!skipped)
X		report_file_xfer_rate("last file",this_file_xfer_count,1);
X	wrefresh(win);
X	this_file_start_seconds = 0;
X
X}	/* end of report_file_close */
X
X/*+-------------------------------------------------------------------------
X	report_comm_baud_rate(baud_rate)
X
X baud rate: row 7 col 14 length 5
X--------------------------------------------------------------------------*/
Xreport_comm_baud_rate(baud_rate)
Xunsigned int baud_rate;
X{
X	char tstr8[8];
X
X	zcurses_baud_rate = baud_rate;
X
X	if(no_curses)
X	{
X		return;
X	}
X
X	clear_area(win,7,14,5);
X	if(baud_rate == 0)
X		waddstr(win,"?");
X	else
X
X	{
X		sprintf(tstr8,"%-5u",baud_rate);
X		waddstr(win,tstr8);
X	}
X	wrefresh(win);
X
X}	/* end of report_comm_baud_rate */
X
X/*+-------------------------------------------------------------------------
X	report_file_byte_io(count)
X--------------------------------------------------------------------------*/
Xreport_file_byte_io(count)
Xlong count;
X{
X
X	total_data_chars_xfered += (long)count;
X	this_file_xfer_count = count;
X
X	if(no_curses)
X	{
X		if(count)
X		{
X			no_curses_newline();
X			printf("Transferred %lu bytes for this file\r\n",count);
X			no_curses_newline();
X		}
X		return;
X	}
X
X	if(total_data_chars_xfered)
X	{
X		sprintf(s128,"Total file bytes transferred: %lu",
X			total_data_chars_xfered);
X		report_str(s128,-1);
X	}
X
X}	/* end of report_file_byte_io */
X
X/* end of zcurses.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
echo 'File z/zcurses.c is complete' &&
$TOUCH -am 0725125991 'z/zcurses.c' &&
chmod 0644 z/zcurses.c ||
echo 'restore of z/zcurses.c failed'
Wc_c="`wc -c < 'z/zcurses.c'`"
test 38433 -eq "$Wc_c" ||
	echo 'z/zcurses.c: original size 38433, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= z/zdebug.c ==============
if test -f 'z/zdebug.c' -a X"$1" != X"-c"; then
	echo 'x - skipping z/zdebug.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting z/zdebug.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'z/zdebug.c' &&
X/* see zcurses.c report_lasthdr() */
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
Xint header_debug = 0;
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125991 'z/zdebug.c' &&
chmod 0644 z/zdebug.c ||
echo 'restore of z/zdebug.c failed'
Wc_c="`wc -c < 'z/zdebug.c'`"
test 224 -eq "$Wc_c" ||
	echo 'z/zdebug.c: original size 224, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= z/zmodem.c ==============
if test -f 'z/zmodem.c' -a X"$1" != X"-c"; then
	echo 'x - skipping z/zmodem.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting z/zmodem.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'z/zmodem.c' &&
X/*+-------------------------------------------------------------------------
X	zmodem.c - ZMODEM protocol primitives
X    based on code by Chuck Forsberg
X
X  Entry point Functions:
X	zsbhdr(type,hdr) send binary header
X	zshhdr(type,hdr) send hex header
X	zgethdr(hdr,eflag) receive header - binary or hex
X	zsdata(buf,len,frameend) send data
X	zrdata(buf,len) receive data
X	stohdr(pos) store position data in Txhdr
X	long rclhdr(hdr) recover position offset from header
X
X  Defined functions:
X	noxrd7()
X	rclhdr(hdr)
X	stohdr(pos)
X	zdlread()
X	zgeth1()
X	zgethdr(hdr,eflag)
X	zgethex()
X	zputhex(c)
X	zrbhdr(hdr)
X	zrbhdr32(hdr)
X	zrdat32(buf,length)
X	zrdata(buf,length)
X	zrhhdr(hdr)
X	zsbh32(hdr,type)
X	zsbhdr(type,hdr)
X	zsda32(buf,length,frameend)
X	zsdata(buf,length,frameend)
X	zsendline(c)
X	zshhdr(type,hdr)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "zmodem.h"			/* wht */
X#include "lint_args.h"
X
Xextern char s128[];				/* wht */
Xextern int Zctlesc;				/* wht */
Xextern int Zmodem;				/* wht */
Xextern long cr3tab[];			/* wht */
Xextern unsigned Baudrate;		/* wht */
Xextern unsigned short crctab[];	/* wht */
X
Xint Rxtimeout = 100;		/* Tenths of seconds to wait for something */
X
X#if !defined(UNSL)
X#define UNSL
X#endif
X
X
X
Xstatic lastsent;	/* Last char we sent */
Xstatic evenp;		/* Even parity seen on header */
X
X/* Globals used by ZMODEM functions */
Xchar Attn[ZATTNLEN+1];	/* Attention string rx sends to tx on err */
Xchar Rxhdr[4];		/* Received header */
Xchar Txhdr[4];		/* Transmitted header */
Xint Crc32;		/* Display flag indicating 32 bit CRC being received */
Xint Crc32t;		/* Display flag indicating 32 bit CRC being sent */
Xint Rxcount;		/* Count of data bytes received */
Xint Rxframeind;		/* ZBIN ZBIN32,or ZHEX type of frame received */
Xint Rxtimeout;	/* Tenths of seconds to wait for something */
Xint Rxtype;		/* Type of header received */
Xint Txfcs32;		/* TURE means send binary frames with 32 bit FCS */
Xint Zrwindow;	/* RX window size (controls garbage count) */
Xlong Rxpos;	/* Received file position */
Xlong Txpos;	/* Transmitted file position */
X
Xchar *frametypes[] = 
X{
X	"Carrier Lost",		/* -3 */
X	"TIMEOUT",			/* -2 */
X	"ERROR",			/* -1 */
X/* #define FTOFFSET 3 moved to zmodem.h */
X	"ZRQINIT",
X	"ZRINIT",
X	"ZSINIT",
X	"ZACK ",
X	"ZFILE",
X	"ZSKIP",
X	"ZNAK ",
X	"ZABORT",
X	"ZFIN ",
X	"ZRPOS",
X	"ZDATA",
X	"ZEOF ",
X	"ZFERR",
X	"ZCRC ",
X	"ZCHALLENGE",
X	"ZCOMPL",
X	"ZCAN ",
X	"ZFREECNT",
X	"ZCOMMAND",
X	"ZSTDERR",
X	"xxxxx"
X#define FRTYPES 22	/* Total number of frame types in this array */
X	/*  not including psuedo negative entries */
X};
X
Xstatic char masked[] = "8 bit transparent path required";
Xstatic char badcrc[] = "Bad CRC";
X
X/* Send ZMODEM binary header hdr of type type */
Xzsbhdr(type,hdr)
Xint type;
Xregister unsigned char *hdr;
X{
X	register int n;
X	register unsigned crc;
X
X	report_tx_ind(1);
X	sprintf(s128,"hdr %s %ld",frametypes[type+FTOFFSET],rclhdr(hdr));
X	report_last_txhdr(s128,0);
X
X	xsendline(ZPAD); 
X	xsendline(ZDLE);
X
X	if(Crc32t=Txfcs32)
X		zsbh32(type,hdr);
X	else 
X	{
X		xsendline(ZBIN); 
X		zsendline(type); 
X		crc = updcrc(type,0);
X
X		for(n=4; --n >= 0; ++hdr)
X		{
X			zsendline(*hdr);
X			crc = updcrc(*hdr,crc);
X		}
X		crc = updcrc(0,updcrc(0,crc));
X		zsendline(crc>>8);
X		zsendline(crc);
X	}
X	if(type != ZDATA)
X		flushline();
X	report_tx_ind(0);
X}
X
X
X/* Send ZMODEM binary header hdr of type type */
Xzsbh32(type,hdr)
Xint type;
Xregister char *hdr;
X{
X	register int n;
X	register UNSL long crc;
X
X	report_tx_ind(1);
X	xsendline(ZBIN32);  
X	zsendline(type);
X	crc = 0xFFFFFFFFL; 
X	crc = UPDC32(type,crc);
X
X	for(n=4; --n >= 0; ++hdr)
X	{
X		crc = UPDC32((0377 & *hdr),crc);
X		zsendline(*hdr);
X	}
X	crc = ~crc;
X	for(n=4; --n >= 0;)
X	{
X		zsendline((int)crc);
X		crc >>= 8;
X	}
X	report_tx_ind(0);
X}
X
X/* Send ZMODEM HEX header hdr of type type */
Xzshhdr(type,hdr)
Xint type;
Xregister unsigned char *hdr;
X{
X	register int n;
X	register unsigned short crc;
X
X	report_tx_ind(1);
X
X	sprintf(s128,"hdr %s %ld",frametypes[type+FTOFFSET],rclhdr(hdr));
X	report_last_txhdr(s128,0);
X	sendline(ZPAD); 
X	sendline(ZPAD); 
X	sendline(ZDLE); 
X	sendline(ZHEX);
X	zputhex(type);
X	Crc32t = 0;
X
X	crc = updcrc(type,0);
X	for(n=4; --n >= 0; ++hdr)
X	{
X		zputhex(*hdr); 
X		crc = updcrc(*hdr,crc);
X/*		crc = updcrc((0377 & *hdr),crc);  original - wht */
X	}
X	crc = updcrc(0,updcrc(0,crc));
X	zputhex(crc>>8); 
X	zputhex(crc);
X
X	/* Make it printable on remote machine */
X	sendline(015); 
X	sendline(012);
X	/*
X	 * Uncork the remote in case a fake XOFF has stopped data flow
X	 */
X	if(type != ZFIN && type != ZACK)
X		sendline(021);
X	flushline();
X	report_tx_ind(0);
X}
X
X/*
X * Send binary array buf of length length,with ending ZDLE sequence frameend
X */
Xstatic char *Zendnames[] = { "ZCRCE","ZCRCG","ZCRCQ","ZCRCW"};
X
Xzsdata(buf,length,frameend)
Xregister unsigned char *buf;
Xint length;
Xint frameend;
X{
X	register unsigned short crc;
X
X	report_tx_ind(1);
X
X	sprintf(s128,"data %s %d bytes",Zendnames[frameend-ZCRCE&3],length);
X	report_last_txhdr(s128,0);
X	if(Crc32t)
X		zsda32(buf,length,frameend);
X	else 
X	{
X		crc = 0;
X		for(;--length >= 0; ++buf)
X		{
X			zsendline(*buf); 
X			crc = updcrc(*buf,crc);
X		}
X		xsendline(ZDLE); 
X		xsendline(frameend);
X		crc = updcrc(frameend,crc);
X
X		crc = updcrc(0,updcrc(0,crc));
X		zsendline(crc>>8); 
X		zsendline(crc);
X	}
X	if(frameend == ZCRCW)
X	{
X		xsendline(XON);  
X		flushline();
X	}
X	report_tx_ind(0);
X
X}
X
Xzsda32(buf,length,frameend)
Xregister char *buf;
Xint length;
Xint frameend;
X{
X	register int c;
X	register UNSL long crc;
X
X	report_tx_ind(1);
X
X	crc = 0xFFFFFFFFL;
X	for(;--length >= 0; ++buf)
X	{
X		c = *buf & 0377;
X		if(c & 0140)
X			xsendline(lastsent = c);
X		else
X			zsendline(c);
X		crc = UPDC32(c,crc);
X	}
X	xsendline(ZDLE); 
X	xsendline(frameend);
X	crc = UPDC32(frameend,crc);
X
X	crc = ~crc;
X	for(length=4; --length >= 0;)
X	{
X		zsendline((int)crc);  
X		crc >>= 8;
X	}
X	report_tx_ind(0);
X}
X
X/*
X * Receive array buf of max length with ending ZDLE sequence
X *  and CRC.  Returns the ending character or error code.
X *  NB: On errors may store length+1 bytes!
X */
Xzrdata(buf,length)
Xregister char *buf;
Xint length;
X{
X	register int c;
X	register unsigned short crc;
X	register char *end;
X	register int d;
X
X	report_rx_ind(1);
X
X	if(Rxframeind == ZBIN32)
X	{
X		report_rx_ind(0);
X		return(zrdat32(buf,length));
X	}
X
X	crc = Rxcount = 0;  
X	end = buf + length;
X	while(buf <= end)
X	{
X		if((c = zdlread()) & ~0377)
X		{
Xcrcfoo:
X			switch(c)
X			{
X			case GOTCRCE:
X			case GOTCRCG:
X			case GOTCRCQ:
X			case GOTCRCW:
X				crc = updcrc(((d=c)&0377),crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = updcrc(c,crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = updcrc(c,crc);
X				if(crc & 0xFFFF)
X				{
X					report_str(badcrc,0);
X					report_rx_ind(0);
X					return(ERROR);
X				}
X				Rxcount = length - (end - buf);
X				report_rxblklen(Rxcount);
X				sprintf(s128,"data %s %d bytes",
X					Zendnames[d-GOTCRCE&3],Rxcount);
X				report_last_rxhdr(s128,0);
X				report_rx_ind(0);
X				return(d);
X			case GOTCAN:
X				report_str("Sender Cancelled",1);
X				report_rx_ind(0);
X				return(ZCAN);
X			case TIMEOUT:
X				report_str("TIMEOUT",0);
X				report_rx_ind(0);
X				return(c);
X			default:
X				report_str("Bad data subpacket",0);
X				report_rx_ind(0);
X				return(c);
X			}
X		}
X		*buf++ = c;
X		crc = updcrc(c,crc);
X	}
X	report_str("Data subpacket too long",0);
X	report_rx_ind(0);
X	return(ERROR);
X}
X
Xzrdat32(buf,length)
Xregister char *buf;
Xint length;
X{
X	register int c;
X	register UNSL long crc;
X	register char *end;
X	register int d;
X
X	report_rx_ind(1);
X	crc = 0xFFFFFFFFL;  
X	Rxcount = 0;  
X	end = buf + length;
X	while(buf <= end)
X	{
X		if((c = zdlread()) & ~0377)
X		{
Xcrcfoo:
X			switch(c)
X			{
X			case GOTCRCE:
X			case GOTCRCG:
X			case GOTCRCQ:
X			case GOTCRCW:
X				d = c;  
X				c &= 0377;
X				crc = UPDC32(c,crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = UPDC32(c,crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = UPDC32(c,crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = UPDC32(c,crc);
X				if((c = zdlread()) & ~0377)
X					goto crcfoo;
X				crc = UPDC32(c,crc);
X				if(crc != 0xDEBB20E3)
X				{
X					report_str(badcrc,0);
X					report_rx_ind(0);
X					return(ERROR);
X				}
X				Rxcount = length - (end - buf);
X				report_rxblklen(Rxcount);
X				sprintf(s128,"data %s %d bytes",
X					Zendnames[d-GOTCRCE&3],Rxcount);
X				report_last_rxhdr(s128,0);
X				report_rx_ind(0);
X				return(d);
X			case GOTCAN:
X				report_str("Sender Canceled",1);
X				report_rx_ind(0);
X				return(ZCAN);
X			case TIMEOUT:
X				report_str("TIMEOUT",0);
X				report_rx_ind(0);
X				return(c);
X			default:
X				report_str("Bad data subpacket",0);
X				report_rx_ind(0);
X				return(c);
X			}
X		}
X		*buf++ = c;
X		crc = UPDC32(c,crc);
X	}
X	report_str("Data subpacket too long",0);
X	report_rx_ind(0);
X	return(ERROR);
X}
X
X
X/*
X * Read a ZMODEM header to hdr,either binary or hex.
X *  eflag controls local display of non zmodem characters:
X *	0:  no display
X *	1:  display printing characters only
X *	2:  display all non ZMODEM characters
X *  On success,set Zmodem to 1,set Rxpos and return type of header.
X *   Otherwise return negative on error.
X *   Return ERROR instantly if ZCRCW sequence,for fast error recovery.
X */
Xzgethdr(hdr,eflag)
Xchar *hdr;
Xint eflag;
X{
Xregister int c,n,cancount;
X
X	report_rx_ind(1);
X	n = Zrwindow + Baudrate;	/* Max bytes before start of frame */
X	Rxframeind = Rxtype = 0;
X
Xstartover:
X	cancount = 5;
Xagain:
X	/* Return immediate ERROR if ZCRCW sequence seen */
X	switch(c = readline(Rxtimeout))
X	{
X	case RCDO:
X	case TIMEOUT:
X		goto fifi;
X	case CAN:
Xgotcan:
X		if(--cancount <= 0)
X		{
X			c = ZCAN; 
X			goto fifi;
X		}
X		switch(c = readline(1))
X		{
X		case TIMEOUT:
X			goto again;
X		case ZCRCW:
X			c = ERROR;
X			/* **** FALL THRU TO **** */
X		case RCDO:
X			goto fifi;
X		default:
X			break;
X		case CAN:
X			if(--cancount <= 0)
X			{
X				c = ZCAN; 
X				goto fifi;
X			}
X			goto again;
X		}
X		/* **** FALL THRU TO **** */
X	default:
Xagn2:
X		if( --n == 0)
X		{
X			report_str("Garbage count exceeded",1);
X			report_last_rxhdr("Noise",0);
X			report_rx_ind(0);
X			return(ERROR);
X		}
X		goto startover;
X	case ZPAD|0200:		/* This is what we want. */
X	case ZPAD:		/* This is what we want. */
X		evenp = c & 0200;
X		break;
X	}
X	cancount = 5;
Xsplat:
X	switch(c = noxrd7())
X	{
X	case ZPAD:
X		goto splat;
X	case RCDO:
X	case TIMEOUT:
X		goto fifi;
X	default:
X		goto agn2;
X	case ZDLE:		/* This is what we want. */
X		break;
X	}
X
X	switch(c = noxrd7())
X	{
X	case RCDO:
X	case TIMEOUT:
X		goto fifi;
X	case ZBIN:
X		Rxframeind = ZBIN;  
X		Crc32 = FALSE;
X		c =  zrbhdr(hdr);
X		break;
X	case ZBIN32:
X		Crc32 = Rxframeind = ZBIN32;
X		c =  zrbhdr32(hdr);
X		break;
X	case ZHEX:
X		Rxframeind = ZHEX;  
X		Crc32 = FALSE;
X		c =  zrhhdr(hdr);
X		break;
X	case CAN:
X		goto gotcan;
X	default:
X		goto agn2;
X	}
X	Rxpos = hdr[ZP3] & 0377;
X	Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
X	Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
X	Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
Xfifi:
X	switch(c)
X	{
X	case GOTCAN:
X		c = ZCAN;
X		/* **** FALL THRU TO **** */
X	case ZNAK:
X	case ZCAN:
X	case ERROR:
X	case TIMEOUT:
X	case RCDO:
X		sprintf(s128,"Got %s",frametypes[c+FTOFFSET]);
X		report_str(s128,0);
X		/* **** FALL THRU TO **** */
X	default:
X		if(c >= -3 && c <= FRTYPES)
X			sprintf(s128,"hdr %s %ld",frametypes[c+FTOFFSET],Rxpos);
X		else
X			sprintf(s128,"hdr 0x%02x? %ld",c,Rxpos);
X		report_last_rxhdr(s128,0);
X	}
X	report_rx_ind(0);
X	return(c);
X}
X
X/* Receive a binary style header (type and position) */
Xzrbhdr(hdr)
Xregister char *hdr;
X{
X	register int c,n;
X	register unsigned short crc;
X
X	if((c = zdlread()) & ~0377)
X		return(c);
X	Rxtype = c;
X	crc = updcrc(c,0);
X
X	for(n=4; --n >= 0; ++hdr)
X	{
X		if((c = zdlread()) & ~0377)
X			return(c);
X		crc = updcrc(c,crc);
X		*hdr = c;
X	}
X	if((c = zdlread()) & ~0377)
X		return(c);
X	crc = updcrc(c,crc);
X	if((c = zdlread()) & ~0377)
X		return(c);
X	crc = updcrc(c,crc);
X	if(crc & 0xFFFF)
X	{
X		if(evenp)
X			report_str(masked,1);
X		report_str(badcrc,0);
X		return(ERROR);
X	}
X#if defined(ZMODEM)
X	Protocol = ZMODEM;
X#endif
X	Zmodem = 1;
X	return(Rxtype);
X}
X
X/* Receive a binary style header (type and position) with 32 bit FCS */
Xzrbhdr32(hdr)
Xregister char *hdr;
X{
X	register int c,n;
X	register UNSL long crc;
X
X	if((c = zdlread()) & ~0377)
X		return(c);
X	Rxtype = c;
X	crc = 0xFFFFFFFFL; 
X	crc = UPDC32(c,crc);
X
X	for(n=4; --n >= 0; ++hdr)
X	{
X		if((c = zdlread()) & ~0377)
X			return(c);
X		crc = UPDC32(c,crc);
X		*hdr = c;
X	}
X	for(n=4; --n >= 0;)
X	{
X		if((c = zdlread()) & ~0377)
X			return(c);
X		crc = UPDC32(c,crc);
X	}
X	if(crc != 0xDEBB20E3)
X	{
X		if(evenp)
X			report_str(masked,1);
X		report_str(badcrc,0);
X		return(ERROR);
X	}
X#if defined(ZMODEM)
X	Protocol = ZMODEM;
X#endif
X	Zmodem = 1;
X	return(Rxtype);
X}
X
X
X/* Receive a hex style header (type and position) */
Xzrhhdr(hdr)
Xchar *hdr;
X{
X	register int c;
X	register unsigned short crc;
X	register int n;
X
X	if((c = zgethex()) < 0)
X		return(c);
X	Rxtype = c;
X	crc = updcrc(c,0);
X
X	for(n=4; --n >= 0; ++hdr)
X	{
X		if((c = zgethex()) < 0)
X			return(c);
X		crc = updcrc(c,crc);
X		*hdr = c;
X	}
X	if((c = zgethex()) < 0)
X		return(c);
X	crc = updcrc(c,crc);
X	if((c = zgethex()) < 0)
X		return(c);
X	crc = updcrc(c,crc);
X	if(crc & 0xFFFF)
X	{
X		report_str(badcrc,0); 
X		return(ERROR);
X	}
X	if(readline(1) == '\r')	/* Throw away possible cr/lf */
X		readline(1);
X#if defined(ZMODEM)
X	Protocol = ZMODEM;
X#endif
X	Zmodem = 1; 
X	return(Rxtype);
X}
X
X/* Send a byte as two hex digits */
Xzputhex(c)
Xregister int c;
X{
X	static char digits[]	= "0123456789abcdef";
X
X	sendline(digits[(c&0xF0)>>4]);
X	sendline(digits[(c)&0xF]);
X}
X
X/*
X * Send character c with ZMODEM escape sequence encoding.
X *  Escape XON,XOFF. Escape CR following @ (Telenet net escape)
X */
Xzsendline(c)
Xint c;
X{
X
X	/* Quick check for non control characters */
X	if(c & 0140)
X		xsendline(lastsent = c);
X	else 
X	{
X		switch(c &= 0377)
X		{
X		case ZDLE:
X			xsendline(ZDLE);
X			xsendline(lastsent = (c ^= 0100));
X			break;
X		case 015:
X		case 0215:
X			if(!Zctlesc && (lastsent & 0177) != '@')
X				goto sendit;
X			/* **** FALL THRU TO **** */
X		case 020:
X		case 021:
X		case 023:
X		case 0220:
X		case 0221:
X		case 0223:
X			xsendline(ZDLE);
X			c ^= 0100;
Xsendit:
X			xsendline(lastsent = c);
X			break;
X		default:
X			if(Zctlesc && ! (c & 0140))
X			{
X				xsendline(ZDLE);
X				c ^= 0100;
X			}
X			xsendline(lastsent = c);
X		}
X	}
X}
X
X/* Decode two lower case hex digits into an 8 bit byte value */
Xzgethex()
X{
X	register int c;
X
X	c = zgeth1();
X	return(c);
X}
Xzgeth1()
X{
X	register int c,n;
X
X	if((c = noxrd7()) < 0)
X		return(c);
X	n = c - '0';
X	if(n > 9)
X		n -= ('a' - ':');
X	if(n & ~0xF)
X		return(ERROR);
X	if((c = noxrd7()) < 0)
X		return(c);
X	c -= '0';
X	if(c > 9)
X		c -= ('a' - ':');
X	if(c & ~0xF)
X		return(ERROR);
X	c += (n<<4);
X	return(c);
X}
X
X/*
X * Read a byte,checking for ZMODEM escape encoding
X *  including CAN*5 which represents a quick abort
X */
Xzdlread()
X{
X	register int c;
X
Xagain:
X	/* Quick check for non control characters */
X	if((c = readline(Rxtimeout)) & 0140)
X		return(c);
X	switch(c)
X	{
X	case ZDLE:
X		break;
X	case 023:
X	case 0223:
X	case 021:
X	case 0221:
X		goto again;
X	default:
X		if(Zctlesc && !(c & 0140))
X		{
X			goto again;
X		}
X		return(c);
X	}
Xagain2:
X	if((c = readline(Rxtimeout)) < 0)
X		return(c);
X	if(c == CAN && (c = readline(Rxtimeout)) < 0)
X		return(c);
X	if(c == CAN && (c = readline(Rxtimeout)) < 0)
X		return(c);
X	if(c == CAN && (c = readline(Rxtimeout)) < 0)
X		return(c);
X	switch(c)
X	{
X	case CAN:
X		return(GOTCAN);
X	case ZCRCE:
X	case ZCRCG:
X	case ZCRCQ:
X	case ZCRCW:
X		return(c | GOTOR);
X	case ZRUB0:
X		return(0177);
X	case ZRUB1:
X		return(0377);
X	case 023:
X	case 0223:
X	case 021:
X	case 0221:
X		goto again2;
X	default:
X		if(Zctlesc && ! (c & 0140))
X		{
X			goto again2;
X		}
X		if((c & 0140) ==  0100)
X			return(c ^ 0100);
X		break;
X	}
X	sprintf(s128,"Bad escape sequence %x",c);
X	report_str(s128,0);
X	return(ERROR);
X}
X
X/*
X * Read a character from the modem line with timeout.
X *  Eat parity,XON and XOFF characters.
X */
Xnoxrd7()
X{
X	register int c;
X
X	for(;;)
X	{
X		if((c = readline(Rxtimeout)) < 0)
X			return(c);
X		switch(c &= 0177)
X		{
X		case XON:
X		case XOFF:
X			continue;
X		default:
X			if(Zctlesc && !(c & 0140))
X				continue;
X		case '\r':
X		case '\n':
X		case ZDLE:
X			return(c);
X		}
X	}
X}
X
X/* Store long integer pos in Txhdr */
Xstohdr(pos)
Xlong pos;
X{
X	Txhdr[ZP0] = pos;
X	Txhdr[ZP1] = pos>>8;
X	Txhdr[ZP2] = pos>>16;
X	Txhdr[ZP3] = pos>>24;
X}
X
X/* Recover a long integer from a header */
Xlong
Xrclhdr(hdr)
Xregister char *hdr;
X{
X	register long l;
X
X	l = (hdr[ZP3] & 0377);
X	l = (l << 8) | (hdr[ZP2] & 0377);
X	l = (l << 8) | (hdr[ZP1] & 0377);
X	l = (l << 8) | (hdr[ZP0] & 0377);
X	return(l);
X}
X
X/* end of zmodem.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125991 'z/zmodem.c' &&
chmod 0644 z/zmodem.c ||
echo 'restore of z/zmodem.c failed'
Wc_c="`wc -c < 'z/zmodem.c'`"
test 16620 -eq "$Wc_c" ||
	echo 'z/zmodem.c: original size 16620, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= z/zmodem.h ==============
if test -f 'z/zmodem.h' -a X"$1" != X"-c"; then
	echo 'x - skipping z/zmodem.h (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting z/zmodem.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'z/zmodem.h' &&
X/*+-------------------------------------------------------------------------
X	zmodem.h -- common include filefor ecurz/ecusz
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */
X
X#if defined(M_UNIX)
X#define OS "UNIX"
X#undef M_XENIX
X#endif
X
X#ifdef __STDC__
X#define VOLATILE volatile
X#else
X#define VOLATILE
X#endif
X
X#if !defined(OS)
X#if !defined(M_XENIX)
X#define XENIX
X#endif
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <termio.h>
X#include <sys/ioctl.h>
X#include <string.h>
X#define MODE2OK
X
X#if !defined(READCHECK)
X#if defined(FIONREAD)
X#define READCHECK
X#endif
X#if defined(SYSV)
X#define READCHECK
X#endif
X#endif
X
X#define ACK 6
X#define CAN ('X'&037)
X#define CPMEOF 032
X#define ENQ 005
X#define EOT 4
X#define ERROR (-1)
X#define ERRORMAX 5
X#define FALSE 0
X#define NAK 025
X#define OK 0
X#define PATHLEN 257	/* ready for 4.2 bsd ? */
X#define RCDO (-3)
X#define SOH 1
X#define STX 2
X#define TIMEOUT (-2)
X#define TRUE 1
X#define UNIXFILE 0xF000	/* The S_IFMT file mask bit for stat */
X#define WANTCRC 0103	/* send C not NAK to get crc not checksum */
X
X#define WANTG 0107	/* Send G not NAK to get nonstop batch xmsn */
X#define WCEOT (-10)
X#define XOFF ('s'&037)
X#define XON ('q'&037)
X
X/*
X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
X *  NOTE: First argument must be in range 0 to 255.
X *        Second argument is referenced twice.
X * 
X * Programmers may incorporate any or all code into their programs, 
X * giving proper credit within the source. Publication of the 
X * source routines is permitted so long as proper credit is given 
X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
X * Omen Technology.
X */
X
X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ (cp))
X#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
X
X
X#define ZPAD '*'	/* 052 Padding character begins frames */
X#define ZDLE 030	/* Ctrl-X Zmodem escape - `ala BISYNC DLE */
X#define ZDLEE (ZDLE^0100)	/* Escaped ZDLE as transmitted */
X#define ZBIN 'A'	/* Binary frame indicator */
X#define ZHEX 'B'	/* HEX frame indicator */
X#define ZBIN32 'C'	/* Binary frame with 32 bit FCS */
X
X/* Frame types (see array "frametypes" in zm.c) */
X#define ZRQINIT	0	/* Request receive init */
X#define ZRINIT	1	/* Receive init */
X#define ZSINIT 2	/* Send init sequence (optional) */
X#define ZACK 3		/* ACK to above */
X#define ZFILE 4		/* File name from sender */
X#define ZSKIP 5		/* To sender: skip this file */
X#define ZNAK 6		/* Last packet was garbled */
X#define ZABORT 7	/* Abort batch transfers */
X#define ZFIN 8		/* Finish session */
X#define ZRPOS 9		/* Resume data trans at this position */
X#define ZDATA 10	/* Data packet(s) follow */
X#define ZEOF 11		/* End of file */
X#define ZFERR 12	/* Fatal Read or Write error Detected */
X#define ZCRC 13		/* Request for file CRC and response */
X#define ZCHALLENGE 14	/* Receiver's Challenge */
X#define ZCOMPL 15	/* Request is complete */
X#define ZCAN 16		/* Other end canned session with CAN*5 */
X#define ZFREECNT 17	/* Request for free bytes on filesystem */
X#define ZCOMMAND 18	/* Command from sending program */
X#define ZSTDERR 19	/* Output to standard error, data follows */
X
X/* ZDLE sequences */
X#define ZCRCE 'h'	/* CRC next, frame ends, header packet follows */
X#define ZCRCG 'i'	/* CRC next, frame continues nonstop */
X#define ZCRCQ 'j'	/* CRC next, frame continues, ZACK expected */
X#define ZCRCW 'k'	/* CRC next, ZACK expected, end of frame */
X#define ZRUB0 'l'	/* Translate to rubout 0177 */
X#define ZRUB1 'm'	/* Translate to rubout 0377 */
X
X/* zdlread return values (internal) */
X/* -1 is general error, -2 is timeout */
X#define GOTOR 0400
X#define GOTCRCE (ZCRCE|GOTOR)	/* ZDLE-ZCRCE received */
X#define GOTCRCG (ZCRCG|GOTOR)	/* ZDLE-ZCRCG received */
X#define GOTCRCQ (ZCRCQ|GOTOR)	/* ZDLE-ZCRCQ received */
X#define GOTCRCW (ZCRCW|GOTOR)	/* ZDLE-ZCRCW received */
X#define GOTCAN	(GOTOR|030)	/* CAN*5 seen */
X
X/* Byte positions within header array */
X#define ZF0	3	/* First flags byte */
X#define ZF1	2
X#define ZF2	1
X#define ZF3	0
X#define ZP0	0	/* Low order 8 bits of position */
X#define ZP1	1
X#define ZP2	2
X#define ZP3	3	/* High order 8 bits of file position */
X
X/* Bit Masks for ZRINIT flags byte ZF0 */
X#define CANFDX	01	/* Rx can send and receive true FDX */
X#define CANOVIO	02	/* Rx can receive data during disk I/O */
X#define CANBRK	04	/* Rx can send a break signal */
X#define CANCRY	010	/* Receiver can decrypt */
X#define CANLZW	020	/* Receiver can uncompress */
X#define CANFC32	040	/* Receiver can use 32 bit Frame Check */
X#define ESCCTL 0100	/* Receiver expects ctl chars to be escaped */
X#define ESC8   0200	/* Receiver expects 8th bit to be escaped */
X
X/* Parameters for ZSINIT frame */
X#define ZATTNLEN 32	/* Max length of attention string */
X/* Bit Masks for ZSINIT flags byte ZF0 */
X#define TESCCTL 0100	/* Transmitter expects ctl chars to be escaped */
X#define TESC8   0200	/* Transmitter expects 8th bit to be escaped */
X
X/* Parameters for ZFILE frame */
X/* Conversion options one of these in ZF0 */
X#define ZCBIN	1	/* Binary transfer - inhibit conversion */
X#define ZCNL	2	/* Convert NL to local end of line convention */
X#define ZCRESUM	3	/* Resume interrupted file transfer */
X/* Management include options, one of these ored in ZF1 */
X#define ZMSKNOLOC	0200	/* Skip file if not present at rx */
X/* Management options, one of these ored in ZF1 */
X#define ZMMASK	037	/* Mask for the choices below */
X#define ZMNEWL	1	/* Transfer if source newer or longer */
X#define ZMCRC	2	/* Transfer if different file CRC or length */
X#define ZMAPND	3	/* Append contents to existing file (if any) */
X#define ZMCLOB	4	/* Replace existing file */
X#define ZMNEW	5	/* Transfer if source newer */
X	/* Number 5 is alive ... */
X#define ZMDIFF	6	/* Transfer if dates or lengths different */
X#define ZMPROT	7	/* Protect destination file */
X/* Transport options, one of these in ZF2 */
X#define ZTLZW	1	/* Lempel-Ziv compression */
X#define ZTCRYPT	2	/* Encryption */
X#define ZTRLE	3	/* Run Length encoding */
X/* Extended options for ZF3, bit encoded */
X#define ZXSPARS	64	/* Encoding for sparse file operations */
X
X/* Parameters for ZCOMMAND frame ZF0 (otherwise 0) */
X#define ZCACK1	1	/* Acknowledge, then do command */
X
X/* FTOFFSET is offset for frametypes array in ecuzm.c */
X#define FTOFFSET 3
X
Xlong rclhdr();
X
X#include "lint_args.h"
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125991 'z/zmodem.h' &&
chmod 0644 z/zmodem.h ||
echo 'restore of z/zmodem.h failed'
Wc_c="`wc -c < 'z/zmodem.h'`"
test 6517 -eq "$Wc_c" ||
	echo 'z/zmodem.h: original size 6517, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= sea/ecusea.c ==============
if test -f 'sea/ecusea.c' -a X"$1" != X"-c"; then
	echo 'x - skipping sea/ecusea.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting sea/ecusea.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'sea/ecusea.c' &&
Xchar *revision = "3.10";	/* cannot be longer than 7 chars (blk0.sender) */
X
X/* #define TABLE_CRC16 */
X#ifdef M_XENIX
X#define NO_SELECT
X#endif
X
X/*+-------------------------------------------------------------------------
X	ecusea.c - SEAlink - Sliding window file transfer protocol
X
X  Defined functions:
X	arg_token(parsestr,termchars)
X	cancel_transaction(sig)
X	crc_update(c,crc)
X	fname_split(cmd,arg,arg_max_quan,narg_rtn)
X	fname_too_long(fname)
X	fname_truncated()
X	getspeed(code)
X	lgetc_timeout(tenths)
X	lgetc_timeout_SIGALRM()
X	main(argc,argv,envp)
X	receive_block(buf)
X	receive_file()
X	send_comm_block(blk,blknum)
X	send_file(name)
X	send_file_block(fp,blknum)
X	set_sf_state(place,new_state)
X	set_utime_1980(filename,secs_since_1980)
X	sf_state_text(state)
X	wait_for_rcvr_response()
X	xmit_ack(blknum)
X	xmit_cancel()
X	xmit_nak(blknum)
X
Xecu adaptation by W. Tucker
Xmodelled after MSDOS sealink.c, which carried the following proviso:
X
X              MS-DOS Version 1.20, created on 08/05/87
X              at 17:51:40 (C) COPYRIGHT 1986,87 by
X              System Enhancement Associates; ALL RIGHTS
X              RESERVED By: Thom Henderson
X
X              You are granted a license to use this
X              code in your programs, and to adapt it to
X              your particular situation and needs,
X              subject only to the following conditions:
X              1) You must refer to it as the SEAlink
X              protocol, and you must give credit to
X              System Enhancement Associates.  2) If you
X              modify it in such a way that your version
X              cannot converse with the original code as
X              supplied by us, then you should refer to
X              it as "SEAlink derived", or as a
X              "variation of SEAlink", or words to that
X              effect.  In short, we're not asking for
X              any money, but we'd like to get some
X              credit for our work.
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:03-18-1991-22:49-wht@n4hgf-ISC 2.2 has struct timeval in sys/time.h */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <fcntl.h>
X#include <termio.h>
X#include <sys/ioctl.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <time.h>
X#include <memory.h>
X#if !defined(NO_SELECT)
X#if defined(M_SYSV)	/* SCO */
X# include <sys/select.h>
X#else
X# include <sys/time.h>
X#endif
X#endif
X
X#include "lint_args.h"
X
X/* Various system constants */
X#define WINDOW		6					/* maximum size of window */
X#define TIMEOUT	0x0FFF
X#define OFFSET_1980	(time_t)315547200	/* time offset for 1970 <-> 1980 */
X
X/*
X * The section of code that is compiled when NAKEOT is defined is in the
X * original MS-DOS version 1.16 routine.  Its purpose is to send a NAK when
X * an EOT is received during receive_file(), apparently to confirm that this is
X * indeed the end of file.  However, in certain (apparently non - standard)
X * versions of the protocol, it is possible that the program will report an
X * error when in fact there isn't one.  Comment this out at your discretion.
X */
X#define NAKEOT
X
X/* SEAlink block zero data structure */
Xtypedef struct blk0
X{
X	long length;			/* length */
X	time_t secs_since_1980;	/* creation/last mod in secs since 1/1/80 */
X	char filename[17];		/* file name */
X	char sender[15];		/* sending program */
X	char send_no_acks;		/* true if rcvr need not ack */
X	char filler[87];		/* fill to 128 bytes */
X}	BLK0;
X
X/* protocol characters */
X#define SOH	0x01
X#define EOT	0x04
X#define ACK	0x06
X#define NAK	0x15
X#define CAN	0x18
X
X/*  send_file state (sf_state) values */
X#define SFS_GND		0	/* Ground state, ACK or NAK expected */
X#define SFS_ACK		1	/* ACK received */
X#define SFS_NAK		2	/* NAK received */
X#define SFS_ACKW	3	/* ACK, block# received */
X#define SFS_NAKW	4	/* NAK, block# received */
X#define SFS_RGND	5	/* Returning to ground state */
Xint sf_state;
X
Xint allow_slide = 1;	/* sliding windows allowed */
Xint crc_in_use;			/* check type, 1 = CRC, 0 = checksum */
Xchar *dfile = "/tmp/ecuSEA.log";
Xint error_count = 0;	/* total number of errors */
Xint iofd = 0;			/* file descriptor to use */
Xint no_ack_mode = 1;	/* true of ACKs not required */
Xint rf_done = 0;		/* receive file done */
Xint sf_ackw_count;		/* count of sliding ACKs seen */
Xint sf_ackblk;			/* number of last block ACKed */
Xint sf_blknum;			/* number of next block to send */
Xint sf_lastnum;			/* number of last block sent */
Xint sf_nakquan;			/* number of sequential NAKs */
Xint sf_slide;			/* true if sliding window */
X
Xint sending_flag = -1;		/* send == 1, receive == 0, bad usage == -1 */
Xint log_packets = 0;
Xlong rx_char_count = 0;
Xlong tx_char_count = 0;
Xint Filcnt = 0;
Xint npaths = 0;
Xchar curr_dir[256];
Xchar s128[128];
Xunsigned baud_rate;
Xint exit_code;
Xint sent_EOT = 0;
X
Xstruct termio tio;
Xstruct termio tio0;
X
Xjmp_buf	lgetc_timeout_setjmp;
X
X/* CRC16 routine; finish CRC calculation for compare */
X
X#ifdef TABLE_CRC16
X
X/* crctab calculated by Mark G. Mendel,Network Systems Corporation */
Xunsigned short crctab[256] = 
X{
X	0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
X	0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
X	0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
X	0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
X	0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
X	0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
X	0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
X	0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
X	0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
X	0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
X	0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
X	0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
X	0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
X	0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
X	0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
X	0xFF9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
X	0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
X	0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
X	0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
X	0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
X	0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
X	0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
X	0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
X	0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
X	0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
X	0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
X	0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
X	0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
X	0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
X	0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
X	0xef1f,0xFF3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
X	0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
X};
X
X/*+-------------------------------------------------------------------------
X  updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
X  NOTE: First argument must be in range 0 to 255.
X        Second argument is referenced twice.
X  Programmers may incorporate any or all code into their programs, giving
X  proper credit within the source.  Publication of the source routines is
X  permitted so long as proper credit is given to Stephen Satchell,
X  Satchell Evaluations and Chuck Forsberg, Omen Technology.
X--------------------------------------------------------------------------*/
X#define crc_update(ch,crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ ch)
X
X#else /* calculated crc */
X
X/*+-------------------------------------------------------------------------
X	crc_update(c,crc)
X--------------------------------------------------------------------------*/
Xunsigned short
Xcrc_update(c,crc)
Xregister c;
Xregister unsigned crc;
X{
Xregister count;
X
X	for(count = 8; --count >= 0;)
X	{
X		if(crc & 0x8000)
X		{
X			crc <<= 1;
X			crc += (((c <<= 1) & 0400) != 0);
X			crc ^= 0x1021;
X		}
X		else 
X		{
X			crc <<= 1;
X			crc += (((c <<= 1) & 0400) != 0);
X		}
X	}
X	return(crc);
X}	/* end of crc_update */
X#endif /* crc calc selection */
X
X/*+-----------------------------------------------------------------------
X	arg_token(parsestr,termchars)
X
XGet next token from string parsestr ((char *)0 on 2nd, 3rd, etc.
Xcalls), where tokens are nonempty strings separated by runs of chars
Xfrom termchars.  Writes nulls into parsestr to end tokens.
Xtermchars need not remain constant from call to call.
X
XTreats multiple occurrences of a termchar as one delimiter (does not
Xallow null fields).
X------------------------------------------------------------------------*/
X#if defined(M_UNIX)
Xstatic char *arg_token_static = (char *)0;
Xchar *arg_token(parsestr,termchars)
Xchar *parsestr;
Xchar *termchars;
X{
Xregister char *parseptr;
Xchar *token;
X
X	if(parsestr == (char *)0 && arg_token_static == (char *)0)
X		return((char *)0);
X
X	if(parsestr)
X		parseptr = parsestr;
X	else
X       parseptr = arg_token_static;
X
X	while(*parseptr)
X	{
X		if(!strchr(termchars,*parseptr))
X			break;
X		parseptr++;
X	}
X
X	if(!*parseptr)
X	{
X		arg_token_static = (char *)0;
X		return((char *)0);
X	}
X
X	token = parseptr;
X	if(*token == '\'')
X	{
X		token++;
X		parseptr++;
X		while(*parseptr)
X		{
X			if(*parseptr == '\'')
X			{
X				arg_token_static = parseptr + 1;
X				*parseptr = 0;
X				return(token);
X			}
X			parseptr++;
X		}
X		arg_token_static = (char *)0;
X		return(token);
X	}
X	while(*parseptr)
X	{
X		if(strchr(termchars,*parseptr))
X		{
X			*parseptr = 0;
X			arg_token_static = parseptr + 1;
X			while(*arg_token_static)
X			{
X				if(!strchr(termchars,*arg_token_static))
X					break;
X				arg_token_static++;
X			}
X			return(token);
X		}
X		parseptr++;
X	}
X	arg_token_static = (char *)0;
X	return(token);
X}	/* end of arg_token */
X#endif
X
X/*+-------------------------------------------------------------------------
X	fname_split(cmd,arg,arg_max_quan,&narg)
X--------------------------------------------------------------------------*/
X#if defined(M_UNIX)
Xvoid
Xfname_split(cmd,arg,arg_max_quan,narg_rtn)
Xchar *cmd;
Xchar **arg;
Xint arg_max_quan;
Xint *narg_rtn;
X{
Xregister itmp;
Xregister narg;
X
X	for(itmp = 0; itmp < arg_max_quan; itmp++)
X		arg[itmp] = (char *)0;
X	arg[0] = arg_token(cmd,"/");
X
X	for(narg = 1; narg < arg_max_quan; ++narg)
X	{
X		if((arg[narg] = arg_token((char *)0,"/")) == (char *)0) 
X			break;
X	}
X
X	*narg_rtn = narg;
X
X}	/* end of fname_split */
X#endif
X
X#if defined(M_UNIX)
X#define MAX_COMPONENT_LEN	14
X#define MAX_PATH_COMPONENTS	16
Xstatic char trunc_fname[257];
Xstatic char *trunc_components[MAX_PATH_COMPONENTS];
Xstatic int trunc_components_quan;
Xstatic int trunc_absolute_path;
X#endif
X
X/*+-------------------------------------------------------------------------
X	fname_too_long(fname) - check for any pathname component too long
X--------------------------------------------------------------------------*/
X#if defined(M_UNIX)
Xint
Xfname_too_long(fname)
Xregister char *fname;
X{
Xregister int itmp;
Xregister char **cpptr;
X
X	if(trunc_absolute_path = (*fname == '/'))
X		fname++;
X	strncpy(trunc_fname,fname,sizeof(trunc_fname) - 1);
X	fname_split(trunc_fname,trunc_components,
X		MAX_PATH_COMPONENTS,&trunc_components_quan);
X	itmp = trunc_components_quan;
X	cpptr = trunc_components;
X	while(itmp--)
X	{
X		if(strlen(*cpptr) > MAX_COMPONENT_LEN)
X			return(1);
X		cpptr++;
X	}
X	return(0);
X}	/* end of fname_too_long */
X#endif
X
X/*+-------------------------------------------------------------------------
X	fname_truncated() - build truncated path last checked by fname_too_long
X--------------------------------------------------------------------------*/
X#if defined(M_UNIX)
Xchar *
Xfname_truncated()
X{
Xregister int icomp;
Xchar new_fname[257];
Xregister char *cptr = new_fname;
X
X	if(trunc_absolute_path)
X	{
X		*cptr = '/';
X		*(cptr + 1) = 0;
X	}
X	else
X		*cptr = 0;
X	for(icomp = 0; icomp < trunc_components_quan; icomp++)
X	{
X		if(strlen(trunc_components[icomp]) > MAX_COMPONENT_LEN)
X			*(trunc_components[icomp] + MAX_COMPONENT_LEN) = 0;
X		strcat(cptr,trunc_components[icomp]);
X		if(icomp < trunc_components_quan - 1)
X			strcat(cptr,"/");
X	}
X	strcpy(trunc_fname,cptr);
X	return(trunc_fname);
X
X}	/* end of fname_truncated */
X#endif
X
X/*+-------------------------------------------------------------------------
X	xmit_cancel()
X--------------------------------------------------------------------------*/
Xvoid
Xxmit_cancel()
SHAR_EOF
true || echo 'restore of sea/ecusea.c failed'
fi
echo 'End of ecu310 part 23'
echo 'File sea/ecusea.c is continued in part 24'
echo 24 > _shar_seq_.tmp
exit 0
--------------------------------------------------------------------
Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.


