home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
ecu
/
part20
< prev
next >
Wrap
Text File
|
1991-08-05
|
55KB
|
1,845 lines
Newsgroups: comp.sources.misc
From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Subject: v21i072: ecu - ECU async comm package rev 3.10, Part20/37
Message-ID: <1991Aug4.162955.18462@sparky.IMD.Sterling.COM>
X-Md4-Signature: ee232688f5c5c1de75c5389a2f90b4eb
Date: Sun, 4 Aug 1991 16:29:55 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Posting-number: Volume 21, Issue 72
Archive-name: ecu/part20
Environment: SCO, XENIX, ISC
Supersedes: ecu3: Volume 16, Issue 25-59
---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is ecu310.20 (part 20 of ecu310)
# do not concatenate these parts, unpack them in order with /bin/sh
# file help/ecuhelp.src 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" != 20; 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 help/ecuhelp.src'
else
echo 'x - continuing file help/ecuhelp.src'
sed 's/^X//' << 'SHAR_EOF' >> 'help/ecuhelp.src' &&
XUsage: parity [ None | Even | Odd ]
X
XThis command controls the parity of characters transmitted by the
Xkeyboard. Issuing the command with no parameter displays the current
Xsetting. When the parameter is supplied, only the first character is
Xrequired. Even or odd parity implies seven data bits; no parity implies
Xeight data bits. Parity of incoming characters is not checked.
X
XThe setting may be automatically changed as the result of a 'dial'
Xcommand. See also the 'baud' and 'dial' command descriptions.
X#--------------------------------------------------------------------
X%pid
XUsage: pid
X
XThis command displays the process id of the ecu transmitter process, the
Xecu receiver process and the process ids of ecu's parent and group.
X#--------------------------------------------------------------------
X%ptrace
XUsage: ptrace [ 0 | 1 | on | off]
X
XThis command controls whether or not procedure execution is to be
Xtraced.
X#--------------------------------------------------------------------
X%pwd
XUsage: pwd
X
XThis command prints the current working directory of the ecu process.
X#--------------------------------------------------------------------
X%rk
XUsage: rk
X
XThis command searches the PATH list for 'ckermit' (Columbia University
XC-Kermit) and invokes it to receive files. See the ecu documentation
Xfor modifications necessary to ckermit for ecu operation. The file
X~/.kermrc must be set up to have any desired initialization paraeters
Xyou desire. Refer to C-Kermit documentation for more information.
X#--------------------------------------------------------------------
X%rs
XUsage: rs
X
XThis command invokes a SEAlink receive protocol.
X#--------------------------------------------------------------------
X%redial
XUsage: redial [<retry-count> [<pause-interval>]]
X
XThis command redials a number previously dialed with the 'dial' command.
XModem status is tested and multiple retries may be made. <retry-count>
Xspecifies how many retries are to be made. <pause-interval> specifies
Xhow many seconds the program pauses after a failure to connect. You
Xmust specify <retry-count> in order to specify <pause-interval>. The
Xdefault value for <retry-count> is 10, for <pause-interval> is 60.
X
XYou should know that in some jurisdictions, it is ILLEGAL to dial the
Xsame telephone number more than a specified number of times during some
Xinterval of time. In any case, specifying <pause-interval> less than 15
Xseconds is silently changed to 15 seconds.
X#--------------------------------------------------------------------
X%rev
XUsage: rev
X
XThis command displays ecu's revision, the transmitter process id and the
Xdate and time ecu was made.
X#--------------------------------------------------------------------
X%rx
XUsage: rx
X
XThis command invokes a modified version of Chuck Forsberg's rz program
X(version 1.31) to receive files from the remote system using XMODEM/CRC.
X
XAfter entering the command, you are prompted as to whether or not file
XCR/LF characters are to be converted to newlines. If you are
Xtransferring text files from a system which contain CR/LF line
Xterminators, you must answer yes to this question. You should answer no
Xwhen transferring binary files, such as executables, .arc files and the
Xlike. File transfer progress is presented on a visual display. To
Xabort the transfer, press your interrupt key (usually DEL unless reset
Xwith stty(C)).
X#--------------------------------------------------------------------
X%ry
XUsage: ry
X
XThis command invokes a modified version of Chuck Forsberg's rz program
X(version 1.31) to receive files from the remote system using YMODEM
Xbatch with CRC-16 error correction. The YMODEM is "true YMODEM", not
XXMODEM-1k. File transfer progress is presented on a visual display. To
Xabort the transfer, press your interrupt key (usually DEL unless reset
Xwith stty(C)).
X#--------------------------------------------------------------------
X%rz
XUsage: rz
X
XThis command invokes a modified version of Chuck Forsberg's rz program
X(version 1.44) to receive files from the remote system using
XZMODEM/CRC32. File transfer progress is presented on a visual display.
XTo abort the transfer, press your interrupt key (usually DEL unless
Xreset with stty(C)).
X#--------------------------------------------------------------------
X%sk
XUsage: sk [<file-list>]
X
XThis command searches the PATH list for 'ckermit' (Columbia University
XC-Kermit) and invokes it to send files. The file ~/.kermrc must be set
Xup to have any desired initialization paraeters you desire. See the ecu
Xdocumentation for modifications necessary to ckermit for ecu operation.
X
XAfter entering the command, you are prompted as to whether or not file
Xnewline characters are to be converted to CR/LF. If you are
Xtransferring text files to a system which requires CR/LF line
Xterminators, you must answer yes to this question. You should answer no
Xwhen transferring binary files, such as executables, .arc files and the
Xlike. You are prompted to enter a list of files to send, which may
Xcontain one or more wildcard specifications.
X
XThe file ~/.kermrc must be set up to have any desired initialization
Xparameters you desire. Refer to C-Kermit documentation for more
Xinformation.
X#--------------------------------------------------------------------
X%ss
XUsage: ss [<file-list>]
X
XThis command invokes a SEAlink file transmission protocol.
X#--------------------------------------------------------------------
X%stat
XUsage: stat
X
XThis command displays statistics about ecu usage.
X
XExample display when not connected to a remote system:
XDate/time: 06-14-1988 11:40:35 (UTC 15:40)
XTotal chars transmitted: 178
XTotal chars received: 3681
X
XDate/time: 06-14-1988 14:41:24 (UTC 18:41)
XConnected to CompuHost (555-1234) at 14:40:57
XParameters: 2400-N-1 Connect time: 00:01:27
XTotal chars transmitted: 234 (since CONNECT 142)
XTotal chars received: 2278 (since CONNECT 1478)
X#--------------------------------------------------------------------
X%sx
XUsage: sx [<file-name>]
X
XThis command invokes a modified version of Chuck Forsberg's sz program
X(version 1.44) to send a file to the remote system using XMODEM/CRC.
X
XAfter entering the command, you are prompted as to whether or not file
XCR/LF characters are to be converted to newlines. If you are
Xtransferring text files from a system which contain CR/LF line termi-
Xnators, you must answer yes to this question. You should answer no when
Xtransferring binary files, such as executables, .arc files and the like.
X
XYou are prompted to enter a filename to send. File transfer progress is
Xpresented on a visual display. To abort the transfer, press your
Xinterrupt key (usually DEL unless reset with stty(C)).
X#--------------------------------------------------------------------
X%sy
XUsage: sy [<file-list>]
X
XThis command invokes a modified version of Chuck Forsberg's sz program
X(version 1.44) to send file(s) to the remote system using YMODEM/CRC.
X
XYou are prompted to enter filename(s) to send, which may consist of one
Xor more wildcard specifications. File transfer progress is presented on
Xa visual display. To abort the transfer, press your interrupt key
X(usually DEL unless reset with stty(C)).
X#--------------------------------------------------------------------
X%sz
XUsage: sz [<file-list>]
X
XThis command invokes a modified version of Chuck Forsberg's sz program
X(version 1.44) to send file(s) to the remote system using ZMODEM/CRC32.
X
XYou are prompted to enter filename(s) to send, which may consist of one
Xor more wildcard specifications. File transfer progress is presented on
Xa visual display. To abort the transfer, press your interrupt key
X(usually DEL unless reset with stty(C)).
X
XNote: if you specify sending only newer files and the remote receiver
Xdoes not support the feature, it may skip (reject) all your files.
XRetry the transfer specifying 'N' to 'Transfer only newer files'.
X#--------------------------------------------------------------------
X%time
XUsage: time
X
XThis command displays the local date and time as well as the current UTC.
X#--------------------------------------------------------------------
X%tty
XUsage: tty
X
XThis command displays the current console tty name.
X#--------------------------------------------------------------------
X%exit
XUsage: exit
X
XThis command terminates ecu promptly. If your modem does not drop
Xcarrier upon loss of Data Terminal Ready (DTR), you must use the
X'hangup' command prior to issuing the 'exit' command. It is strongly
Xrecommended that you configure your modem to hang up the phone line when
XDTR drops. A shorthand version of this command exists: '.' is
Xequivalent to 'exit'.
X#--------------------------------------------------------------------
X%xon
XUsage: xon [<arg>]
Xwhere <arg> is on input and output flow control
X off no flow control
X in input flow control
X out output flow control
X
XThis command enables or disables xon/xoff flow control. If the
Xargument is omitted, the current flow control state is displayed.
X#--------------------------------------------------------------------
X%!
XUsage: !
X !<command>
X
XThe '!' command is a shell escape. The environment variable SHELL is
Xread to determine what shell program to execute (e.g., /bin/sh, etc).
XIf '!' is entered by itself, an interactive shell is started; press ^D
Xto exit back to ecu. If <command> is supplied, it is executed by the
Xshell with an immediate return to ecu.
X
XSimilarly,
X '$' causes the communications line to be stdin and stdout
X for the spawned shell
X '-' is similar to '>', except the command is executed directly
X without going through a shell.
X#--------------------------------------------------------------------
X%$
XUsage: $
X $<command>
X
XThe '$' command is a shell escape causing the communications line to be
Xthe stand input and output. The environment variable SHELL is read to
Xdetermine what shell program to execute (e.g., /bin/sh, etc). If '$' is
Xentered by itself, an interactive shell is started; a ^D received from
Xthe communications line causes the shell to terminate and control to be
Xpassed back to ecu. If <command> is supplied, it is executed by the
Xshell with an immediate return to ecu.
X#--------------------------------------------------------------------
X%-
XUsage: -<command>
X
XThe '-' command causes <command> to be executed directly without
Xpassing through a shell (no wildcard expansion or other shell
Xprocessing occurs). Standard input, output and error all are
Xopened to the console. In addition, all other files (including
Xthe communications line) opened by ecu remain open.
X#--------------------------------------------------------------------
X%?
XUsage: ?
X
XThis is an alias for the help command.
X#--------------------------------------------------------------------
X%clrx
XUsage: clrx
X
XThe 'clrx' command simulates receipt of an XON by ECU. It is useful
Xin the rare circumstances that an XOFF is received by ECU from a
Xremote system and no later XON is received.
X#--------------------------------------------------------------------
X%pcmd
XUsage: pcmd <procedure command>
X
XThe 'pcmd' command allows a procedure command to be issued from the
Xinteractive command prompt. It is primarily intended for debugging
Xprocedure commands, but it is available for any use.
X#--------------------------------------------------------------------
X%plog
XUsage: plog [<filename> | off | ]
X
XThe 'plog' command turns on or off procedure logging. If the
Xargument to the command is 'off', logging is turned off, otherwise
Xlogging is started on the specified file. If no argument is specified,
Xthe status of procedure logging is displayed.
X#--------------------------------------------------------------------
X%rtscts
XUsage: rtscts [ y | n | ]
X
XThis SCO-only command turns on or off the driver RTS and CTS flow
Xcontrol. As of this writing, SCO's driver does half duplex (traditional,
Xbrain damaged) flow control if RTSFLOW is enabled. FAS does hardware
Xflow control based on the device magic number, but if you use a device
Xnumber specifying no hardware flow control, RTSFLOW and CTSFLOW can be
Xused to specify SCO-style flow control. Advice: use rts on or off for
XSCO, use appropriate magic numbered device for FAS.
X
Xargument | RTSFLOW | CTSFLOW argument | RTSFLOW | CTSFLOW
X---------+---------+--------- ---------+---------+---------
X off | 0 | 0 0 | 0 | 0
X on | 0 | 1 1 | 0 | 1
X no | 0 | 0 2 | 1 | 0
X yes | 1 | 1 3 | 1 | 1
X#--------------------------------------------------------------------
X%sdname
XUsage: sdname [<filename> | ]
X
XThis command sets or displays the current screen dump filename.
XUntil the command is issued, screen dump data is placed in
X~/.ecu/screen.dump.
X#--------------------------------------------------------------------
X%sgr
XUsage: sgr mode cmd
X
XThis experimental command is used to test the timed read primitive
Xused by ECU. The command <cmd> is sent to the line and a timed
Xread is performed. The data returned is displayed in hexadecimal
Xformat on the console. Refer to source module ecuxenix.c, function
Xsend_get_response() for details.
X#--------------------------------------------------------------------
X%ts
XUsage: ts
X
XThis experimental command displays raw termio structure information
Xfor the console and the tty. It is primarily used in debugging ECU.
X#--------------------------------------------------------------------
X%xlog
XUsage: xlog [y | n]
X
XThis experimental command controls exhaustive logging by the X, Y, and
XZMODEM file transfer protocols to files named /tmp/szNNNNN.log or
X/tmp/rzNNNNN.log where NNNNN is the process id of the transfer process.
X#--------------------------------------------------------------------
X%eto
XUsage: eto [msec]
X
XThis experimental command sets or displays the "escape timeout"
Xfor non-multiscreen function key detection. Use caution: although
Xthe command has a lower limit, you may set the value low enough
Xnot to be able to use the HOME key!
X#--------------------------------------------------------------------
X%nice
XUsage: nice [niceval]
X
XThis command sets or displays the process nice value. The usual
Xrules apply (hint: you might accidently nice4 yourself into not
Xgetting enough CPU!)
X#--------------------------------------------------------------------
X%pushd
XUsage: pushd [ | <dir> ]
X
XThis command either 1) pushes the current directory pathname onto
Xa stack and establishes a new direcctory or 2) shows the current
Xstack. Issuing the command with no argument displays the stack.
X#--------------------------------------------------------------------
X%popd
XUsage: pushd [ | <#> | all ]
X
XThis command pops one, many or all of the entries off diretory stack,
Xrestoring a previous directory. No argument results in one directory
Xbeing popped. A numeric argument pops the stack to a specified level.
X'all' is equal to the numeric value 0 (and may be abbreviasted 'a').
SHAR_EOF
echo 'File help/ecuhelp.src is complete' &&
$TOUCH -am 0725045191 'help/ecuhelp.src' &&
chmod 0644 help/ecuhelp.src ||
echo 'restore of help/ecuhelp.src failed'
Wc_c="`wc -c < 'help/ecuhelp.src'`"
test 26787 -eq "$Wc_c" ||
echo 'help/ecuhelp.src: original size 26787, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ecuungetty/ecuungetty.c ==============
if test -f 'ecuungetty/ecuungetty.c' -a X"$1" != X"-c"; then
echo 'x - skipping ecuungetty/ecuungetty.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ecuungetty/ecuungetty.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuungetty/ecuungetty.c' &&
X#ifndef lint
Xchar *revision = "ecuungetty 3.10";
X#endif
X/*+-------------------------------------------------------------------------
X ecuungetty.c - ecu "ungetty" program
X wht@n4hgf.Mt-Park.GA.US
X
Xecuungetty /dev/ttyxx <bamboozle-str>
Xecuungetty -t /dev/ttyxx <bamboozle-str>
Xecuungetty -r /dev/ttyxx <bamboozle-str>
X
X Defined functions:
X ecu_log_event(pid,logstr)
X errno_text(errnum)
X hangup()
X main(argc,argv,envp)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <fcntl.h>
X#include <errno.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <utmp.h>
X#include "../stdio_lint.h"
X#include "../ecuungetty.h"
X#include "../utmpstatus.h"
X
Xextern struct utmp last_utmp;
X
X/*+-------------------------------------------------------------------------
X ecu_log_event(pid,logstr) - dummy procedure for utmpstat.o
X--------------------------------------------------------------------------*/
Xvoid
Xecu_log_event(pid,logstr)
Xint pid;
Xchar *logstr;
X{
X ;
X} /* end of ecu_log_event */
X
X/*+-------------------------------------------------------------------------
X termecu() - "dummy" for utmpstat.c
XThis particular incantation will only be called if utmp is non-existent
Xor not readable.......
X--------------------------------------------------------------------------*/
Xtermecu()
X{
X exit(UGE_NOTROOT);
X} /* end of hangup */
X
X/*+-------------------------------------------------------------------------
X errno_text(errnum)
X--------------------------------------------------------------------------*/
Xchar *
Xerrno_text(errnum)
Xint errnum;
X{
Xstatic char errstr[12];
X sprintf(errstr,"E%d\n",errnum);
X return(errstr);
X} /* end of errno_text */
X
X/*+-------------------------------------------------------------------------
X main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xint op = 'g'; /* assume "get" operation */
Xint status;
Xint itmp;
Xchar *tty = argv[1];
Xchar *bamboozlement = argv[2];
Xchar *bamboozle();
X
X if(geteuid() != 0)
X exit(UGE_NOTROOT);
X
X if(*argv[1] == '-')
X {
X switch(op = *(argv[1] + 1))
X {
X case 'r':
X case 't':
X break;
X default:
X exit(UGE_BADSWITCH);
X }
X if(argc < 3)
X exit(UGE_BADARGC);
X tty = argv[2];
X bamboozlement = argv[3];
X }
X else if(argc <= 2)
X exit(UGE_BADARGC);
X
X if(getuid() != 0)
X {
X if(strcmp(bamboozlement,bamboozle(getppid())))
X exit(UGE_CALLER);
X }
X
X status = utmp_status(tty);
X
X switch(op)
X {
X case 'g':
X switch(status)
X {
X case US_NOTFOUND: /* not in utmp, or getty dead */
X exit(UG_NOTENAB);
X case US_LOGIN: /* enabled for login, idle */
X kill(last_utmp.ut_pid,SIGUSR1);
X nap(200L);
X exit(UG_ENAB);
X case US_DIALOUT: /* enabled for login, currently dialout */
X case US_LOGGEDIN: /* enabled for login, in use */
X exit(UG_FAIL);
X }
X break;
X
X case 't':
X switch(status)
X {
X case US_NOTFOUND: /* not in utmp, or getty dead */
X exit(UGE_T_NOTFOUND);
X case US_LOGIN: /* enabled for login, idle */
X exit(UGE_T_LOGIN);
X case US_LOGGEDIN: /* enabled for login, in use */
X exit(UGE_T_LOGGEDIN);
X case US_DIALOUT: /* enabled for login, currently dialout */
X exit(UG_RESTART);
X }
X break;
X
X case 'r':
X switch(status)
X {
X case US_NOTFOUND: /* not in utmp, or getty dead */
X case US_LOGIN: /* enabled for login, idle */
X case US_LOGGEDIN: /* enabled for login, in use */
X exit(0);
X case US_DIALOUT: /* enabled for login, currently dialout */
X itmp = 5;
X while(itmp--)
X {
X if(kill(last_utmp.ut_pid,SIGUSR2))
X break;
X nap(100L);
X }
X exit(0);
X }
X break;
X }
X exit(0);
X} /* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of ecuungetty.c */
SHAR_EOF
$TOUCH -am 0725125791 'ecuungetty/ecuungetty.c' &&
chmod 0644 ecuungetty/ecuungetty.c ||
echo 'restore of ecuungetty/ecuungetty.c failed'
Wc_c="`wc -c < 'ecuungetty/ecuungetty.c'`"
test 4034 -eq "$Wc_c" ||
echo 'ecuungetty/ecuungetty.c: original size 4034, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= z/baudtest.c ==============
if test -f 'z/baudtest.c' -a X"$1" != X"-c"; then
echo 'x - skipping z/baudtest.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting z/baudtest.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'z/baudtest.c' &&
X
X/*+-------------------------------------------------------------------------
X baudtest.c
X wht@n4hgf.Mt-Park.GA.US
X
XAlas, on some systems, curses insists on sgtty.h inclusion
Xwhich does not get aslong with termio.h AT ALL
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:12-04-1990-05:36-wht-creation */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <termio.h>
X
Xextern int iofd;
Xextern int no_curses;
Xextern int report_verbosity;
Xextern int report_init_complete;
Xextern char *numeric_revision;
X
X/*+-------------------------------------------------------------------------
X test_tty_and_line_baud()
X
X if non-multiscreen tty baud rate not at least that
X of the attached line, use no curses, but do be a bit more
X verbose than if tty not char special
X
X--------------------------------------------------------------------------*/
Xvoid
Xtest_tty_and_line_baud()
X{
X struct termio tty_termio;
X struct termio line_termio;
X
X memset((char *)&tty_termio,0,sizeof(struct termio));
X memset((char *)&line_termio,0,sizeof(struct termio));
X if(ioctl(0,TCGETA,&tty_termio) || ioctl(iofd,TCGETA,&line_termio) ||
X ((tty_termio.c_cflag & CBAUD) < ((line_termio.c_cflag & CBAUD))))
X {
X fprintf(stderr,"%s %o %o\r\n",numeric_revision,
X (tty_termio.c_cflag & CBAUD), (line_termio.c_cflag & CBAUD));
X no_curses = 1;
X report_verbosity = 1;
X report_init_complete = 1;
X }
X
X} /* end of test_tty_and_line_baud */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of baudtest.c */
SHAR_EOF
$TOUCH -am 0725125991 'z/baudtest.c' &&
chmod 0644 z/baudtest.c ||
echo 'restore of z/baudtest.c failed'
Wc_c="`wc -c < 'z/baudtest.c'`"
test 1559 -eq "$Wc_c" ||
echo 'z/baudtest.c: original size 1559, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= z/ecurz.c ==============
if test -f 'z/ecurz.c' -a X"$1" != X"-c"; then
echo 'x - skipping z/ecurz.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting z/ecurz.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'z/ecurz.c' &&
Xchar *numeric_revision = "ecurz 3.13";
X/*+-------------------------------------------------------------------------
X ecurz.c - X/Y/ZMODEM receive program
X Derived from public domain source by Chuck Forsberg, Omen Technologies
X Adaptation for ecu 1989 wht@n4hgf.Mt-Park.GA.US
X
X Defined functions:
X SIGALRM_handler()
X arg_token(parsestr,termchars)
X bye_bye(sig)
X cancel_transaction(sig)
X close_and_report()
X flushline()
X fname_split(cmd,arg,arg_max_quan,narg_rtn)
X fname_too_long(fname)
X fname_truncated()
X getfree()
X isanylc(str)
X main(argc,argv,envp)
X make_dirs(pathname)
X mkdir(dpath,dmode)
X procheader(name)
X purgeline()
X readline(timeout)
X rzfile()
X rzfiles()
X send_ZFIN_and_exit()
X send_cancel(error)
X sendline(c)
X substr(str,token)
X sys2(shellcmd)
X tryz()
X uncaps(str)
X usage(fail_reason)
X wcgetsec(rxbuf,maxtime)
X wcreceive(argc,argp)
X wcrx()
X wcrxpn(rpn)
X write_sec_to_disk(buf,n)
X xsendline(c)
X
X Usage: ecurz -Z [-abeuy] (ZMODEM)
X ecurz -Y [-abuy] (YMODEM)
X ecurz -X [-abc] file (XMODEM or XMODEM-1k)
X
X -a ASCII transfer (strip CR)
X -b Binary transfer for all files
X -c Use 16 bit CRC (XMODEM)
X -e Escape control characters (ZMODEM)
X -p protect local files (ZMODEM)
X -t <tenths> rx timeout seconds
X -+ force append
X -u convert uppercase filenames to lower case
X -y Yes, clobber existing file if any
X -. line fd to use
X -, log protocol packets
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:04-30-1991-18:33-wht@n4hgf-gcc version coredumping on putc(); use fputc() */
X/*:03-27-1991-21:21-wht@n4hgf-dont bump error count on send ZRPOS */
X/*:02-03-1991-17:27-wht@n4hgf-version number change - see zcurses.c */
X/*:12-18-1990-21:26-wht@n4hgf-better output control */
X/*:10-04-1990-14:01-wht@n4hgf-add file finish warning for me */
X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
X/*:08-23-1990-14:14-wht@n4hgf-sending ZACK was erroneously counted as error */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <stdio.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <ctype.h>
X#include <errno.h>
X#include <fcntl.h>
X#include "zmodem.h"
X#include "lint_args.h"
X
Xchar *strrchr();
X
X#if defined(M_UNIX)
Xchar *fname_truncated();
X#endif
X
Xextern unsigned short crctab[];
Xextern unsigned long total_data_chars_xfered; /* zcurses.c */
Xextern int force_no_curses;
Xextern int errno;
Xextern char *sys_errlist[];
Xextern char Attn[]; /* Attention string rx sends to tx on err */
Xextern int Crc32; /* Display flag indicating 32 bit CRC being received */
Xextern int Rxcount; /* Count of data bytes received */
Xextern char Rxhdr[]; /* Received header */
Xextern char Txhdr[]; /* Transmitted header */
Xextern int Rxtimeout; /* Tenths of seconds to wait for something */
Xextern char s128[128];
X
X/* Max value for VMIN_COUNT is 255. A larger value reduces system
Xoverhead but may evoke kernel bugs. 133 corresponds to an XMODEM/CRC
Xsector */
X#if !defined(VMIN_COUNT)
X#define VMIN_COUNT 133
X#endif
Xunsigned char vmin_count = VMIN_COUNT;
Xint Readnum = VMIN_COUNT; /* num bytes to ask for in read() from modem */
X
X#define DEFBYTL 2000000000L /* default rx file size */
X#define RETRYMAX 5
X
XFILE *fout;
Xchar Lzmanag; /* Local file management request */
Xchar Pathname[PATHLEN];
Xchar curr_dir[256];
Xunsigned char linbuf[VMIN_COUNT];
Xchar secbuf[1025];
Xchar zconv; /* ZMODEM file conversion request */
Xchar zmanag; /* ZMODEM file management request */
Xchar ztrans; /* ZMODEM file transport request */
Xint Batch=0;
Xint Blklen; /* record length of received packets */
Xint Crcflg;
Xint Eofseen; /* indicates cpm eof (^Z) has been received */
Xint Filcnt=0; /* count of number of files opened */
Xint Filemode; /* Unix style mode for incoming file */
Xint Firstsec;
Xint Lastrx;
Xint Lleft=0; /* number of characters in linbuf */
Xint MakeLCPathname=1; /* make received pathname lower case */
Xint Nozmodem = 0; /* If invoked as "rb" */
Xint Rxascii=0; /* receive files in ascii (translate) mode */
Xint Rxbinary=0; /* receive all files in bin mode */
Xint Rxclob=0; /* Clobber existing file */
Xint Thisbinary; /* current file is to be received in bin mode */
Xint Twostop = 0; /* use two stop bits */
Xint Zctlesc; /* Encode control characters */
Xint Zmodem=0; /* ZMODEM protocol requested */
Xint Zrwindow = 1400; /* RX window size (controls garbage count) */
Xint ecusz_flag = 0;
Xint skip_count = 0; /* skipped files */
Xint errors;
Xint iofd = 0;
Xint force_no_curses = 0;
Xint can_on_eof = 0;
Xint log_packets = 0;
Xint npats = 0;
Xint oldBlklen = -1; /* last block length */
Xint this_file_errors = 0;
Xint tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */
Xjmp_buf tohere; /* For the interrupt on RX timeout */
Xlong Bytesleft; /* number of bytes of incoming file left */
Xlong Modtime; /* Unix style mod time for incoming file */
Xlong TotalToReceive = 0L;
Xlong rx_char_count = 0L;
Xlong tx_char_count = 0L;
Xstruct stat fout_stat;
Xtime_t timep[2];
Xunsigned Baudrate;
Xunsigned long this_file_length;
Xint required_type = 0;
Xchar *bottom_label = (char *)0;
Xchar *got_garbage_txt = "got garbage (0x%02x)";
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 substr(str,token)
X
X searches for token in string str returns pointer to token within
X string if found,NULL otherwise
X--------------------------------------------------------------------------*/
Xchar *
Xsubstr(str,token)
Xregister char *str,*token;
X{
Xregister char *ss,*tt;
X
X /* search for first char of token */
X for(ss=str; *str; str++)
X if(*str == *token)
X /* compare token with substring */
X for(ss=str,tt=token; ;)
X {
X if(*tt == 0)
X return(str);
X if(*ss++ != *tt++)
X break;
X }
X return(NULL);
X} /* end of substr */
X
X/*+-------------------------------------------------------------------------
X getfree()
X
X Routine to calculate the free bytes on the current file system ~0
X means many free bytes (unknown)
X--------------------------------------------------------------------------*/
Xlong
Xgetfree()
X{
X return(~0L); /* many free bytes ... */
X} /* end of getfree */
X
X/*+-------------------------------------------------------------------------
X usage(fail_reason)
X--------------------------------------------------------------------------*/
Xvoid
Xusage(fail_reason)
Xchar *fail_reason;
X{
X fprintf(stderr,"%s\n",fail_reason);
X exit(255);
X} /* end of usage */
X
X/*+-------------------------------------------------------------------------
X SIGALRM_handler()
X--------------------------------------------------------------------------*/
Xvoid
XSIGALRM_handler()
X{
X report_tx_ind(0);
X report_rx_ind(0);
X longjmp(tohere,-1);
X} /* end of SIGALRM_handler */
X
X/*+-------------------------------------------------------------------------
X bye_bye(sig)
X--------------------------------------------------------------------------*/
Xvoid
Xbye_bye(sig)
Xint sig;
X{
X exit(sig+128);
X} /* end of bye_bye */
X
X/*+-------------------------------------------------------------------------
X cancel_transaction(can_code)
Xcalled by signal interrupt or terminate to clean things up
X--------------------------------------------------------------------------*/
Xvoid
Xcancel_transaction(can_code)
Xint can_code;
X{
X if(Zmodem)
X zmputs(Attn);
X send_cancel(1);
X mode(0);
X if(can_code >= 0)
X {
X sprintf(s128,"ecurz aborted (signal %d)",can_code);
X report_str(s128,0);
X }
X report_tx_ind(0);
X report_rx_ind(0);
X report_uninit(0);
X bye_bye(can_code);
X
X} /* end of cancel_transaction */
X
X/*+-------------------------------------------------------------------------
X sendline(c) - send a character to DCE
X--------------------------------------------------------------------------*/
Xsendline(c)
Xchar c;
X{
X write(iofd,&c,1);
X ++tx_char_count;
X} /* end of sendline */
X
X/*+-------------------------------------------------------------------------
X xsendline(c)
X--------------------------------------------------------------------------*/
Xxsendline(c)
Xint c;
X{
X sendline(c);
X} /* end of xsendline */
X
X/*+-------------------------------------------------------------------------
X flushline()
X--------------------------------------------------------------------------*/
Xflushline()
X{
X} /* end of flushline */
X
X/*+-------------------------------------------------------------------------
X purgeline() - purge the modem input queue of all characters
X--------------------------------------------------------------------------*/
Xpurgeline()
X{
X Lleft = 0;
X#if defined(M_XENIX) || defined(M_UNIX)
X ioctl(iofd,TCFLSH,0);
X#else
X lseek(iofd,0L,2);
X#endif
X} /* end of purgeline */
X
X/*+-------------------------------------------------------------------------
X wcreceive(argc,argp)
X--------------------------------------------------------------------------*/
Xwcreceive(argc,argp)
Xint argc;
Xchar **argp;
X{
Xregister c;
X
X if(Batch || argc==0)
X {
X Crcflg=1;
X c=tryz();
X if(Zmodem)
X {
X report_protocol_type("ZMODEM");
X report_protocol_crc_type((Crc32) ? "/CRC32" : "/CRC16");
X }
X if(c)
X {
X if(c == ZCOMPL)
X return(OK);
X if(c == ERROR)
X goto fubar;
X c = rzfiles();
X if(c)
X goto fubar;
X } else
X {
X report_protocol_type("YMODEM");
X report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
X for(;;)
X {
X if(wcrxpn(secbuf)== ERROR)
X goto fubar;
X if(secbuf[0]==0)
X return(OK);
X if(procheader(secbuf) == ERROR)
X goto fubar;
X report_str("Receiving data",0);
X if(wcrx()==ERROR)
X goto fubar;
X }
X }
X }
X else
X {
X report_protocol_type("XMODEM");
X report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK");
X Bytesleft = DEFBYTL;
X Filemode = 0;
X Modtime = 0L;
X procheader("");
X strcpy(Pathname,*argp);
X#if defined(M_UNIX)
X if(fname_too_long(Pathname))
X {
X strcpy(s128,"truncated: ");
X strncat(s128,Pathname,sizeof(s128) - 12);
X ecu_log_event(getppid(),s128);
X report_str(s128,-1);
X strcpy(Pathname,fname_truncated());
X }
X#endif
X if((fout=fopen(Pathname,"w")) == NULL)
X {
X sprintf(s128,"%-0.35s: %-0.40s",Pathname,sys_errlist[errno]);
X report_str(s128,1);
X ecu_log_event(getppid(),s128);
X goto fubar;
X }
X
X ++Filcnt;
X report_file_rcv_started( Pathname,0L,Modtime,Filemode);
X this_file_length = 0;
X report_rxpos(0L);
X report_str("Receiving data",0);
X if(wcrx()==ERROR)
X goto fubar;
X }
X return(OK);
Xfubar:
X send_cancel(1);
X if(fout)
X {
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_file_byte_io((long)fout_stat.st_size);
X report_file_close(0);
X fclose(fout);
X }
X return(ERROR);
X} /* end of wcreceive */
X
X/*+-------------------------------------------------------------------------
X wcgetsec(rxbuf,maxtime)
X
X Wcgetsec fetches a Ward Christensen type sector. Returns sector
X number encountered or ERROR if valid sector not received, or CAN CAN
X received or WCEOT if eot sector time is timeout for first char,set to
X 4 seconds thereafter. NO ACK IS SENT IF SECTOR IS RECEIVED OK. Caller
X must do that when he is good and ready to get next sector.
X--------------------------------------------------------------------------*/
Xunsigned int
Xwcgetsec(rxbuf,maxtime)
Xchar *rxbuf;
Xint maxtime;
X{
Xregister unsigned int firstch;
Xregister unsigned short oldcrc;
Xregister unsigned char checksum;
Xregister wcj;
Xregister char *p;
Xint sectcurr;
X
X for(Lastrx=errors=0; errors<RETRYMAX; errors++)
X {
X
X firstch=readline(maxtime);
X if((firstch == STX) || (firstch == SOH))
X {
X oldBlklen = Blklen;
X if(firstch == STX)
X Blklen=1024;
X else
X Blklen=128;
X if(oldBlklen != Blklen)
X report_rxblklen(Blklen);
X
X sectcurr=readline(1);
X if((sectcurr + (oldcrc=readline(1))) == 0xFF)
X {
X oldcrc=checksum=0;
X for(p=rxbuf,wcj=Blklen; --wcj>=0; )
X {
X if((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch,oldcrc);
X checksum += (*p++ = firstch);
X }
X if((firstch=readline(1)) < 0)
X goto bilge;
X if(Crcflg)
X {
X oldcrc=updcrc(firstch,oldcrc);
X if((firstch=readline(1)) < 0)
X goto bilge;
X oldcrc=updcrc(firstch,oldcrc);
X if(oldcrc)
X {
X sprintf(s128,"CRC error = 0x%04x",oldcrc);
X report_str(s128,1);
X }
X else
X {
X Firstsec=0;
X return(sectcurr);
X }
X }
X else if((checksum-firstch)==0)
X {
X Firstsec=0;
X return(sectcurr);
X }
X else
X report_str("checksum error",1);
X }
X else
X {
X report_last_txhdr("Noise",0);
X sprintf(s128,"Sector garbled 0x%x 0x%x",sectcurr,oldcrc);
X report_str(s128,1);
X }
X }
X /* make sure eot really is eot and not just mixmash */
X#if defined(NFGVMIN)
X else if(firstch==EOT && readline(1)==TIMEOUT)
X return(WCEOT);
X#else
X else if(firstch==EOT && Lleft==0)
X return(WCEOT);
X#endif
X else if(firstch==EOT)
X {
X report_str("Noisy EOT",2);
X }
X else if(firstch==CAN)
X {
X if(Lastrx==CAN)
X {
X report_str("Sender CANcelled",1);
X report_last_rxhdr("CAN",1);
X return(ERROR);
X } else
X {
X Lastrx=CAN;
X continue;
X }
X }
X else if(firstch==TIMEOUT)
X {
X if(Firstsec)
X goto humbug;
Xbilge:
X report_str("Timeout",1);
X }
X else
X {
X sprintf(s128,"Got 0x%02x sector header",firstch);
X report_str(s128,1);
X }
X
Xhumbug:
X Lastrx=0;
X while(readline(1)!=TIMEOUT)
X ;
X if(Firstsec)
X {
X sendline(Crcflg?WANTCRC:NAK);
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X Lleft=0; /* Do read next time ... */
X } else
X {
X maxtime=40;
X sendline(NAK);
X report_last_txhdr("NAK",1);
X Lleft=0; /* Do read next time ... */
X }
X }
X /* try to stop the bubble machine. */
X send_cancel(1);
X return(ERROR);
X} /* end of wcgetsec */
X
X/*+-------------------------------------------------------------------------
X wcrxpn(rpn)
X
X Fetch a pathname from the other end. Length is indeterminate as long
X as less than Blklen. During YMODEM xfers, a null string represents no
X more files.
X--------------------------------------------------------------------------*/
Xwcrxpn(rpn)
Xchar *rpn; /* receive a pathname */
X{
Xregister c;
X
X#if defined(NFGVMIN)
X readline(1);
X#else
X purgeline();
X#endif
X
Xet_tu:
X Firstsec=1;
X Eofseen=0;
X sendline(Crcflg?WANTCRC:NAK);
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X Lleft=0; /* Do read next time ... */
X while((c = wcgetsec(rpn,100)) != 0)
X {
X if(c == WCEOT)
X {
X sprintf(s128,"Pathname fetch returned %d",c);
X report_str(s128,1);
X sendline(ACK);
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X readline(1);
X goto et_tu;
X }
X return(ERROR);
X }
X sendline(ACK);
X report_last_txhdr("ACK",0);
X return(OK);
X} /* end of wcrxpn */
X
X/*+-------------------------------------------------------------------------
X write_sec_to_disk(buf,n)
X
X Putsec writes the n characters of buf to receive file fout. If not in
X binary mode, carriage returns, and all characters starting with CPMEOF
X are discarded.
X--------------------------------------------------------------------------*/
Xwrite_sec_to_disk(buf,n)
Xchar *buf;
Xregister n;
X{
Xregister char *p;
X
X if(n == 0)
X return(OK);
X if(Thisbinary)
X {
X for(p=buf; --n>=0; )
X fputc( *p++,fout);
X }
X else
X {
X if(Eofseen)
X return(OK);
X for(p=buf; --n>=0; ++p )
X {
X if( *p == '\r')
X continue;
X if(*p == CPMEOF)
X {
X Eofseen=1;
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X return(OK);
X }
X fputc(*p,fout);
X }
X }
X fflush(fout);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X if(this_file_length != 0)
X {
X int pct;
X sprintf(s128,"Receiving data (%u%% complete)",
X (unsigned int)(
X pct = ((unsigned long)fout_stat.st_size * (unsigned long)100)
X / this_file_length));
X report_str(s128,0);
X }
X return(OK);
X} /* end of write_sec_to_disk */
X
X/*+-------------------------------------------------------------------------
X wcrx() - receive an X/YMODEM sector
X
X Adapted from CMODEM13.C,written by Jack M. Wierda and Roderick W. Hart
X--------------------------------------------------------------------------*/
Xint
Xwcrx()
X{
Xregister unsigned int sectnum,sectcurr;
Xregister unsigned char sendchar;
Xint cblklen; /* bytes to dump this block */
X
X Firstsec=1;
X sectnum=0;
X Eofseen=0;
X sendchar=Crcflg ? WANTCRC : NAK;
X report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0);
X
X for(;;)
X {
X sendline(sendchar); /* send it now,we're ready! */
X if(sendchar == ACK)
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X sectcurr=wcgetsec(secbuf,(sectnum&0177)?50:130);
X sprintf(s128,"Block %d received",sectnum);
X report_last_rxhdr(s128,0);
X fstat(fileno(fout),&fout_stat);
X report_rxpos(fout_stat.st_size);
X if(sectcurr == (sectnum+1 & 0xFF))
X {
X sectnum++;
X cblklen = Bytesleft>Blklen ? Blklen : Bytesleft;
X if(write_sec_to_disk(secbuf,cblklen) == ERROR)
X return(ERROR);
X if((Bytesleft-=cblklen) < 0)
X Bytesleft = 0;
X sendchar=ACK;
X }
X else if(sectcurr == sectnum)
X {
X report_str("Received duplicate Sector",-1);
X sendchar = ACK;
X }
X else if(sectcurr == WCEOT)
X {
X if(close_and_report())
X return(ERROR);
X sendline(ACK);
X report_last_txhdr("ACK",0);
X Lleft=0; /* Do read next time ... */
X return(OK);
X }
X else if(sectcurr==ERROR)
X return(ERROR);
X else
X {
X report_str( "Sync Error",1);
X return(ERROR);
X }
X }
X} /* end of wcrx */
X
X/*+-------------------------------------------------------------------------
X readline(timeout)
X
X read one or more characters timeout is in tenths of seconds
X--------------------------------------------------------------------------*/
Xreadline(timeout)
Xint timeout;
X{
XVOLATILE int n;
Xstatic unsigned char *cdq; /* pointer for removing chars from linbuf */
X
X if(--Lleft >= 0)
X return(*cdq++);
X
X n = timeout/10;
X if(n < 2)
X n = 3;
X if(setjmp(tohere))
X {
X Lleft = 0;
X return(TIMEOUT);
X }
X signal(SIGALRM,SIGALRM_handler);
X alarm(n);
X Lleft = read(iofd,(char *)(cdq = linbuf),Readnum);
X alarm(0);
X rx_char_count += Lleft;
X
X if(Lleft < 1)
X return(TIMEOUT);
X
X --Lleft;
X return(*cdq++);
X
X} /* end of readline */
X
X/*+-------------------------------------------------------------------------
X mkdir(dpath,dmode)
X Directory-creating routines from Public Domain TAR by John Gilmore
X Make a directory. Compatible with the mkdir() system call on 4.2BSD.
X--------------------------------------------------------------------------*/
X#if defined(MD)
X#if (MD != 2)
X#define TERM_SIGNAL(status) ((status) & 0x7F)
X#define TERM_COREDUMP(status) (((status) & 0x80) != 0)
X#define TERM_VALUE(status) ((status) >> 8)
Xmkdir(dpath,dmode)
Xchar *dpath;
Xint dmode;
X{
Xint cpid,status;
Xstruct stat statbuf;
X
X if(stat(dpath,&statbuf) == 0)
X {
X errno = EEXIST; /* Stat worked,so it already exists */
X return(-1);
X }
X
X /* If stat fails for a reason other than non-existence,return error */
X if(errno != ENOENT)
X return(-1);
X
X switch(cpid = fork())
X {
X
X case -1: /* Error in fork() */
X return(-1); /* Errno is set already */
X
X case 0: /* Child process */
X /*
X * Cheap hack to set mode of new directory. Since this
X * child process is going away anyway,we zap its umask.
X * FIXME,this won't suffice to set SUID,SGID,etc. on this
X * directory. Does anybody care?
X */
X status = umask(0); /* Get current umask */
X status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
X execl("/bin/mkdir","mkdir",dpath,(char *)0);
X _exit(-1); /* Can't exec /bin/mkdir */
X
X default: /* Parent process */
X while(cpid != wait(&status)) ; /* Wait for kid to finish */
X }
X
X if(TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0)
X {
X errno = EIO; /* We don't know why,but */
X return(-1); /* /bin/mkdir failed */
X }
X
X return(0);
X} /* end of mkdir */
X#endif /* MD != 2 */
X#endif /* if defined(MD) */
X
X/*+-------------------------------------------------------------------------
X make_dirs(pathname)
X
X Directory-creating routines from Public Domain TAR by John Gilmore
X After a file/link/symlink/dir creation has failed, see if it's because
X some required directory was not present, and if so, create all
X required dirs.
X--------------------------------------------------------------------------*/
X#if defined(MD)
Xmake_dirs(pathname)
Xregister char *pathname;
X{
X register char *p; /* Points into path */
X int madeone = 0; /* Did we do anything yet? */
X int save_errno = errno; /* Remember caller's errno */
X
X if(errno != ENOENT)
X return(0); /* Not our problem */
X
X for(p = strchr(pathname,'/'); p != NULL; p = strchr(p+1,'/'))
X {
X /* Avoid mkdir of empty string,if leading or double '/' */
X if(p == pathname || p[-1] == '/')
X continue;
X /* Avoid mkdir where last part of path is '.' */
X if(p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
X continue;
X *p = 0; /* Truncate the path there */
X if( !mkdir(pathname,0777)) /* Try to create it as a dir */
X {
X sprintf(s128,"Made directory %s",pathname);
X report_str(s128,-1);
X madeone++; /* Remember if we made one */
X *p = '/';
X continue;
X }
X *p = '/';
X if(errno == EEXIST) /* Directory already exists */
X continue;
X /*
X * Some other error in the mkdir. We return to the caller.
X */
X break;
X }
X errno = save_errno; /* Restore caller's errno */
X return(madeone); /* Tell them to retry if we made one */
X} /* end of make_dirs */
X#endif /* MD */
X
X/*+-------------------------------------------------------------------------
X uncaps(str) - make string str lower case
X--------------------------------------------------------------------------*/
Xvoid
Xuncaps(str)
Xregister char *str;
X{
Xregister int itmp;
X
X while(itmp = *str)
X {
X if(isupper(itmp))
X *str = tolower(itmp);
X str++;
X }
X} /* end of uncaps */
X
X/*+-------------------------------------------------------------------------
X isanylc(str) - returns 1 if string str has any lower case letters
X--------------------------------------------------------------------------*/
Xint
Xisanylc(str)
Xregister char *str;
X{
X while(*str)
X {
X if(islower(*str))
X return(1);
X str++;
X }
X return(0);
X} /* end of isanylc */
X
X/*+-------------------------------------------------------------------------
X procheader(name) - process incoming file information header
X--------------------------------------------------------------------------*/
Xint
Xprocheader(name)
Xchar *name;
X{
Xregister char *openmode,*p;
X
X /* set default parameters and overrides */
X openmode = "w";
X Thisbinary = (!Rxascii) || Rxbinary;
X if(Lzmanag)
X zmanag = Lzmanag;
X
X /*
X * Process ZMODEM remote file management requests
X */
X if(!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
X Thisbinary = 0;
X if(zconv == ZCBIN) /* Remote Binary override */
X Thisbinary = 1;
X else if(zmanag == ZMAPND)
X openmode = "a";
X
X report_xfer_mode(Thisbinary ? "BINARY" : "ASCII");
X this_file_errors = 0;
X
X Bytesleft = DEFBYTL;
X Filemode = 0;
X Modtime = 0L;
X this_file_length = 0;
X
X if(strlen(name))
X p = name + 1 + strlen(name);
X else
X p = name;
X
X#if defined(M_UNIX)
X if(fname_too_long(name))
X {
X strcpy(s128,"truncated: ");
X strncat(s128,name,sizeof(s128) - 12);
X ecu_log_event(getppid(),s128);
X report_str(s128,-1);
X name = fname_truncated();
X }
X#endif
X
X if(*p)
X { /* file coming from Unix or DOS system */
X int sscanf_count;
X int SerialNumber;
X int Filesleft;
X long TotalLeft;
X
X sscanf_count = sscanf(p,"%ld%lo%o%d&d&ld",
X &Bytesleft,&Modtime,&Filemode,&SerialNumber,
X &Filesleft,&TotalLeft);
X
X switch(sscanf_count)
X {
X case 6: /* TotalLeft */
X if(!TotalToReceive)
X TotalToReceive = TotalLeft;
X case 5: /* Filesleft */
X if(!npats)
X npats = Filesleft;
X default:
X break;
X }
X
X if((zmanag & ZMMASK) == ZMNEW)
X {
X if(stat(name,&fout_stat) == 0) /* if file accessable ... */
X {
X if(Modtime <= fout_stat.st_mtime) /* ... and not older */
X {
X sprintf(s128,"RECEIVE skipped: %s (same or later date)",
X name);
X report_str(s128 + 8,-1);
X skip_count++;
X report_error_count();
X#if defined(LOG_SKIP)
X ecu_log_event(getppid(),s128);
X#endif
X return(ERROR);
X }
X }
X }
X /* Check for existing file */
X else if(!Rxclob && ((zmanag & ZMMASK) != ZMCLOB) &&
X (fout=fopen(name,"r")))
X {
X fclose(fout);
X sprintf(s128,"RECEIVE skipped: %s (already exists)",name);
X report_str(s128 + 8,-1);
X skip_count++;
X report_error_count();
X#if defined(LOG_SKIP)
X ecu_log_event(getppid(),s128);
X#endif
X return(ERROR);
X }
X
X if(Filemode & UNIXFILE)
X ++Thisbinary;
X ++Filcnt;
X
X report_file_rcv_started( name,
X (Bytesleft != DEFBYTL) ? Bytesleft : 0,Modtime,Filemode);
X report_rxpos(0L);
X report_str("",0); /* get rid of End of File */
X if(Bytesleft != DEFBYTL)
X {
X long min_100;
X this_file_length = Bytesleft;
X min_100 = 2L + (((Bytesleft * 11L)) * 10L) / (Baudrate * 6L);
SHAR_EOF
true || echo 'restore of z/ecurz.c failed'
fi
echo 'End of ecu310 part 20'
echo 'File z/ecurz.c is continued in part 21'
echo 21 > _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.