Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!csd4.milw.wisc.edu!dogie.macc.wisc.edu!indri!polyslo!usc!orion.cf.uci.edu!uci-ics!zardoz!dhw68k!bob From: bob@dhw68k.cts.com (Bob Best) Newsgroups: comp.os.minix Subject: zterm - background zmodem with dialer (Part 1/5) Message-ID: <23577@dhw68k.cts.com> Date: 8 Jun 89 13:30:29 GMT Reply-To: bob@dhw68k.cts.com (Bob Best) Organization: Wolfskill & Dowling residence; Anaheim, CA (USA) Lines: 1372 Here is zterm, an enhancement to minix term providing support for background zmodem transfers and a background dialer with dialing directory. Although zmodem sources have been previously posted to this newsgroup, I received numerous requests for a repost. Hence, this package is complete with all required zmodem source. Please see README for additional details. -------------------cut here---------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 X Makefile 1 X README 1 X bell.c 1 X bgdial 1 X bgzmod 1 X crc.c 2 X crc.man 1 X crctab.c 2 X dial.c 1 X dial.dir 1 X dialer 1 X rbsb.c 1 X rz.c 4 X rz.man 2 X sz.c 5 X sz.man 3 X zm.c 3 X zmodem.h 1 X zterm.c 1 END_OF_FILE if test 716 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1592 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Makefile for Minix zterm serial communications X# with support for background zmodem transfers X# and background dialing X XBINDIR=/usr/bin XZDIR=/usr/lib/zterm X XCFLAGS= X Xall: rz sz dial zterm bell X Xrz: rz.c zm.c zmodem.h rbsb.c crctab.c X cc -DMD=2 -Dstrchr=index -DV7 $(CFLAGS) rz.c -o rz X size rz X Xsz: sz.c zm.c zmodem.h rbsb.c crctab.c X cc -DV7 $(CFLAGS) -DNFGVMIN sz.c -o sz X size sz X Xdial: dial.c X cc $(CFLAGS) dial.c -o dial X Xzterm: zterm.c X cc $(CFLAGS) zterm.c -o zterm X Xbell: bell.c X cc $(CFLAGS) bell.c -o bell X Xinstall: X -mkdir $(ZDIR) X -chmod 755 $(ZDIR) X chown bin $(ZDIR) X rm $(BINDIR)/rb X rm $(BINDIR)/rx X rm $(BINDIR)/sb X rm $(BINDIR)/sx X cp sz rz zterm $(BINDIR) X ln $(BINDIR)/rz $(BINDIR)/rx X ln $(BINDIR)/rz $(BINDIR)/rb X ln $(BINDIR)/sz $(BINDIR)/sx X ln $(BINDIR)/sz $(BINDIR)/sb X -chmod 755 $(BINDIR)/zterm X chown bin $(BINDIR)/zterm X# chgrp bin $(BINDIR)/zterm X -chmod 755 $(BINDIR)/rz X -chmod 755 $(BINDIR)/sz X chown bin $(BINDIR)/rz X chown bin $(BINDIR)/sz X# chgrp bin $(BINDIR)/rz X# chgrp bin $(BINDIR)/sz X cp dial bell bgdial bgzmod dialer $(ZDIR) X -chmod 755 $(ZDIR)/dial X chown bin $(ZDIR)/dial X# chgrp bin $(ZDIR)/dial X -chmod 755 $(ZDIR)/bell X chown bin $(ZDIR)/bell X# chgrp bin $(ZDIR)/bell X -chmod 755 $(ZDIR)/bgdial X chown bin $(ZDIR)/bgdial X# chgrp bin $(ZDIR)/bgdial X -chmod 755 $(ZDIR)/bgzmod X chown bin $(ZDIR)/bgzmod X# chgrp bin $(ZDIR)/bgzmod X -chmod 755 $(ZDIR)/dialer X chown bin $(ZDIR)/dialer X# chgrp bin $(ZDIR)/dialer X chmem =4000 $(BINDIR)/sz X chmem =4000 $(BINDIR)/rz X chmem =1000 $(ZDIR)/bell X chmem =4000 $(ZDIR)/dial X chmem =8000 $(BINDIR)/zterm END_OF_FILE if test 1592 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(3699 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XWed Jun 7 19:29:29 PDT 1989 X XZTERM - Background Zmodem Transfer and Auto Dialer for Minix X hacked by bob best (bob@dhw68k.cts.com) X XThe following hack provides support for zmodem transfers under Minix. XThe term.c (now zterm.c) code has been modified to allow access to the Xsz (send zmodem) and rz (receive zmodem) programs developed by Chuck XForsberg. The actual rz and sz sources used are based on the original X2.0 release dating back to 5/88. I have also included support for a background Xdialer and dialing directory. The dial.c code assumes a Hayes compatible Xmodem ("AT" command set that sends a "CONNECT" string on carrier detect). X XThe file zterm.c uses some hard coded parameters that should be modified Xfor compatibility with your system. The definable constant MODEM is Xcurrently set for /dev/tty1. The constant ZDIR is set for X'/usr/lib/zterm'. The 'dialer' 'dial', 'bgdial', 'bgzmod', and 'bell' Xprograms are all placed in ZDIR by 'make install'. Similarly, the Xprograms 'zterm', 'rz', and 'sz' are placed in /usr/bin. XIf ZDIR is changed in zterm.c the absolute paths must be changed in the Xvarious shell scripts. X XThe dialing directory is formatted as 5 tab separated fields defined as follows: X1) a code number used to refer to a particular entry X2) the telephone number to be dialed X3) the baud rate used for dialing X4) the date and time of the last connection to this system X5) user description of this system (not used by software) XEach field must be separated by exactly one tab character. XA preformatted directory 'dial.dir' has been included. The 'dial.dir' Xshould be located in $HOME, the user's home directory. X XTo access the dialing directory in zterm, type a tilde '~' followed by Xthe character 'd' for dial. To access the zmodem protocol handlers, Xtype a tilde followed by 't' for transfer. You will be prompted for the Xtransfer command. To receive, simply type 'rz'. To send, type 'sz'. XYou will then be prompted for a list of files (shell wildcards accepted) Xto transmit. When the zmodem handlers start execution, zterm will exit Xto the shell. The transfers will continue in the background. Upon Xcompletion, a bell will sound and a message will be displayed on the Xterminal. The user can then return to zterm. Do NOT run zterm while Xthe transfers are taking place. To monitor an ongoing transfer, examine Xthe file /tmp/[rs]zlog. To exit from the terminal, type a tilde Xfollowed by a period '.'. To enter a tilde, type 2 tildes. X XThe automatic dialing code has been designed to continuously dial in the Xbackground until a connection is made. The dialer will cycle through a Xuser selected list of systems to dial. During dialing, the user will be Xable to access a shell to interact with the system. When a connection Xis made, the user will be rudely interrupted with a message to that effect. XIf background dialing must be terminated prior to a connection, hit 'F1' Xfor a process dump, and use the kill command with the 'bgdial' pid. X XThe zterm terminal can be entered or exited at anytime without Xdropping carrier. The user is solely responsible for disconnecting the Xline. This implementation is somewhat messy. On my Xenix system, the Xinterface is simplified via a window manager. If anyone is working on a Xwindow manager or job control for Minix, please notify. XSome locking mechanism should be provided to prevent multiple access Xto the modem. X XIt is not my intent to support this package. For users with particular Xneeds, the source is straightforward and can be easily modified. If you Xhave specific questions, please post them to comp.os.minix. This Xpackage has been tested using only the Evans kernel including the Evans Xtty driver. END_OF_FILE if test 3699 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'bell.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'bell.c'\" else echo shar: Extracting \"'bell.c'\" \(209 characters\) sed "s/^X//" >'bell.c' <<'END_OF_FILE' X#define BELL '\007' X#define DEFCOUNT 3 Xchar c=BELL; Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X int count=DEFCOUNT; X X if (argc > 1) X count=atoi(argv[1]); X while (count--) { X write(1,&c,1); X sleep(1); X } X} X END_OF_FILE if test 209 -ne `wc -c <'bell.c'`; then echo shar: \"'bell.c'\" unpacked with wrong size! fi # end of 'bell.c' fi if test -f 'bgdial' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'bgdial'\" else echo shar: Extracting \"'bgdial'\" \(872 characters\) sed "s/^X//" >'bgdial' <<'END_OF_FILE' X# bgdial - auto-redial till connect X# written by bob best (bob@dhw68k.cts.com) X# XZDIR="/usr/lib/zterm" XTTY="$1" Xshift Xfor i Xdo X set `grep "^${i} " ${HOME}/dial.dir` X lines="$lines $1 $2 $3" Xdone Xwhile : Xdo X set $lines X while : X do X system=$1 X case $system in X "") #break # bug in shell! must use continue X continue 2 X ;; X *) shift X telno=$1 X shift X baud=$1 X shift X# echo "dialing $system $telno $baud" X ${ZDIR}/dial $TTY $telno $baud X case $? in X 0) ${ZDIR}/bell X clr X echo "CONNECTION ESTABLISHED TO $system $telno $baud" X echo "Exit to shell and type 'zterm $baud' to enter terminal" X cp $HOME/dial.dir $HOME/dial.dirbak X sed "s/^\\($system .* .* \\)\\(.*\\)\\( .*\\)/\\1`date|sed -f /tmp/sed.in`\\3/" $HOME/dial.dirbak >$HOME/dial.dir X rm /tmp/dial.menu X rm /tmp/sed.in X exit 0 X ;; X *) ;; X esac X esac X done Xdone END_OF_FILE if test 872 -ne `wc -c <'bgdial'`; then echo shar: \"'bgdial'\" unpacked with wrong size! fi chmod +x 'bgdial' # end of 'bgdial' fi if test -f 'bgzmod' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'bgzmod'\" else echo shar: Extracting \"'bgzmod'\" \(480 characters\) sed "s/^X//" >'bgzmod' <<'END_OF_FILE' X# bgzmod - run zmodem transfers in the background X# called by zterm XZDIR=/usr/lib/zterm Xcommand="$1" Xshift Xcase $command in Xrz) ;; Xsz) for i X do X files="$files $i" X done X ;; X*) echo "Bad command - exiting" >/dev/tty X exit 1; X ;; Xesac X$command -vvv $files # add more v's for more output (see /tmp/[rs]zlog) X#exec /dev/tty X(${ZDIR}/bell;clr;echo "Zmodem Transfers Completed";echo "Exit to shell and type 'zterm' to enter terminal") >/dev/tty X END_OF_FILE if test 480 -ne `wc -c <'bgzmod'`; then echo shar: \"'bgzmod'\" unpacked with wrong size! fi chmod +x 'bgzmod' # end of 'bgzmod' fi if test -f 'crc.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'crc.man'\" else echo shar: Extracting \"'crc.man'\" \(995 characters\) sed "s/^X//" >'crc.man' <<'END_OF_FILE' X X X X CRC(1) MINIX Version 1.3+ (OMEN) CRC(1) X X X X NAME X crc - checksum files X X SYNOPSIS X crc file ... X X DESCRIPTION X For each file, crc calculates and prints a 32-bit CRC, the X byte count, and the file name. It is typically used to X validate files transferred between different systems, and is X useful in detecting subtle disk corruption. Crc uses a X checksum compatible with the DOS version of crc, as well as X the "crc" command in ZCOMM and Professional-YAM (high X reliability communications programs). X X The 32-bit CRC used is the frame check sequence in ADCCP X (ANSI X3.66, also known as FIPS PUB 71 and FED-STD-1003, the X U.S. versions of CCITT's X.25 link-level protocol). X X 32 bit CRC code courtesy Gary S. Brown. X X BUGS X Although most unlikely, files with different data may still X produce the same crc value. X X SEE ALSO X chek(1), tocpm(1), sum(1), wc(1). X X X X X X X X X X X X X X X X X X X X X X X X X X X X X Page 1 (printed 6/6/89) X X X END_OF_FILE if test 995 -ne `wc -c <'crc.man'`; then echo shar: \"'crc.man'\" unpacked with wrong size! fi # end of 'crc.man' fi if test -f 'dial.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dial.c'\" else echo shar: Extracting \"'dial.c'\" \(1981 characters\) sed "s/^X//" >'dial.c' <<'END_OF_FILE' X/* dial.c X * written by bob best (bob@dhw68k.cts.com) X * X * supports Hayes compatible modems X * Usage: dial device telno baudrate X * X * this program is called by the 'dialer' shell script that is part X * of the zterm package posted to comp.os.minix X */ X#include X#include X#include X#include X X#define FAIL 1 X#define SUCCESS 0 X#define BUFLINE 256 X#define CMDLINE 80 X#define TIMEOUT 30 X Xchar *strchr(); Xint alarmsig(); Xint fd; X Xmain(argc,argv) X int argc; X char *argv[]; X{ X char *device; X char *telno; X char cmdbuf[CMDLINE]; X int timeout, baudrate; X char *p; X struct sgttyb sgtty; X X device = argv[1]; X telno = argv[2]; X/* baudrate = atoi(argv[3]);*/ X switch(atoi(argv[3])) { X case 1200: X baudrate=B1200; X break; X case 2400: X baudrate=B2400; X break; X case 9600: X baudrate=B9600; X break; X default: X printf("Bad baudrate %s - exiting\r\n",argv[3]); X exit(1); X } X if ((fd = open(device, O_RDWR)) < 0) { X printf("dial: Can't open device: %s\n", device); X exit(FAIL); X } X X ioctl(fd, TIOCGETP, &sgtty); X sgtty.sg_ispeed = baudrate; X sgtty.sg_ospeed = baudrate; X ioctl(fd, TIOCSETP, &sgtty); X sleep(1); X write(fd,"AT\r",3); X sleep(2); X sprintf(cmdbuf, "ATDT%s\r", telno); X timeout = TIMEOUT; X signal(SIGALRM, alarmsig); X p=cmdbuf; X while (*p) X write(fd, p++, 1); X if (getmodem(timeout)) X exit(FAIL); X else X exit(SUCCESS); X} X Xgetmodem(timer) X int timer; X{ X char c; X register char *p; X char buf[BUFLINE]; X X p = buf; X alarm(timer); X while (read(fd, &c, 1) == 1) { X *p++ = c; X if (p >= buf + BUFLINE) { X alarm(0); X return(FAIL); X } X if (c == '\r') { X if (getCONNECT(buf) == SUCCESS) { X alarm(0); X return(SUCCESS); X } X p=buf; /* reset pointer for next string */ X } X } X alarm(0); X return(FAIL); X} X XgetCONNECT(l) X register char *l; X{ X int len = strlen("CONNECT"); X X while ((l = strchr(l, 'C')) != NULL) { X if (strncmp("CONNECT", l, len) == 0) X return(SUCCESS); X l++; X } X return(FAIL); X} X Xalarmsig() X{ X exit(FAIL); X} END_OF_FILE if test 1981 -ne `wc -c <'dial.c'`; then echo shar: \"'dial.c'\" unpacked with wrong size! fi # end of 'dial.c' fi if test -f 'dial.dir' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dial.dir'\" else echo shar: Extracting \"'dial.dir'\" \(380 characters\) sed "s/^X//" >'dial.dir' <<'END_OF_FILE' Xa0 5551234 2400 Jan 1 00:00 System 0 Xa1 5551234 2400 Jan 1 00:00 System 1 Xa2 5551234 2400 Jan 1 00:00 System 2 Xa3 5551234 2400 Jan 1 00:00 System 3 Xa4 5551234 2400 Jan 1 00:00 System 4 Xa5 5551234 2400 Jan 1 00:00 System 5 Xa6 5551234 2400 Jan 1 00:00 System 6 Xa7 5551234 2400 Jan 1 00:00 System 7 Xa8 5551234 2400 Jan 1 00:00 System 8 Xa9 5551234 2400 Jan 1 00:00 System 9 END_OF_FILE if test 380 -ne `wc -c <'dial.dir'`; then echo shar: \"'dial.dir'\" unpacked with wrong size! fi # end of 'dial.dir' fi if test -f 'dialer' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dialer'\" else echo shar: Extracting \"'dialer'\" \(1421 characters\) sed "s/^X//" >'dialer' <<'END_OF_FILE' X# Auto Dialer shell script for minix X# Written by bob best (bob@dhw68k.cts.com) X# XZDIR=/usr/lib/zterm XTTY=$1 X Xcat >/tmp/dial.menu <<'FOO' X MINIX TERMINAL DIALER X D Dial once only X A Auto-redial till connect X Q Quit to Terminal X XFOO X X# this is a hack, but I couldn't fix the shell Xcat >/tmp/sed.in <<'FOO' Xs/^[A-Z].. \([A-Z].*\):.*/\1/ XFOO X Xwhile : Xdo X clr X cat /tmp/dial.menu X echo -n " Enter your choice: " X read choice X case $choice in X a|A) clr X cat $HOME/dial.dir X echo -n "Enter the code name of the system(s) you wish to dial: " X read choice X ${ZDIR}/bgdial $TTY $choice & X sleep 2 X clr X echo "Dialing in progress - exiting terminal & returning to shell" X exit 1 X ;; X d|D) clr X cat $HOME/dial.dir X echo -n "Enter the code name of the system you wish to dial: " X read choice X set `grep "^${choice} " ${HOME}/dial.dir` X echo "dialing $choice $2 $3" X ${ZDIR}/dial $TTY $2 $3 X case $? in X 0) ${ZDIR}/bell 1 X echo "CONNECTION ESTABLISHED TO $choice $2" X cp $HOME/dial.dir $HOME/dial.dirbak X sed "s/^\\($choice .* .* \\)\\(.*\\)\\( .*\\)/\\1`date|sed -f /tmp/sed.in`\\3/" $HOME/dial.dirbak >$HOME/dial.dir X rm /tmp/dial.menu X rm /tmp/sed.in X exit 0 X ;; X *) echo "NO CONNECTION" X sleep 2 X ;; X esac X ;; X q|Q) rm /tmp/dial.menu X rm /tmp/sed.in X exit 0 X ;; X *) echo "Invalid character" X ;; X esac Xdone END_OF_FILE if test 1421 -ne `wc -c <'dialer'`; then echo shar: \"'dialer'\" unpacked with wrong size! fi chmod +x 'dialer' # end of 'dialer' fi if test -f 'rbsb.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rbsb.c'\" else echo shar: Extracting \"'rbsb.c'\" \(6735 characters\) sed "s/^X//" >'rbsb.c' <<'END_OF_FILE' X/* X * X * Rev 03-06-1988 X * This file contains Unix specific code for setting terminal modes, X * very little is specific to ZMODEM or YMODEM per se (that code is in X * sz.c and rz.c). The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM X * are also in this file, a fast table driven macro version X * X * V7/BSD HACKERS: SEE NOTES UNDER mode(2) !!! X * X * This file is #included so the main file can set parameters such as HOWMANY. X * See the main files (rz.c/sz.c) for compile instructions. X */ X X#ifdef V7 X#include X#include X#include X#define OS "V7/BSD" X#ifdef LLITOUT Xlong Locmode; /* Saved "local mode" for 4.x BSD "new driver" */ Xlong Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */ X#include X#endif X#endif X X#ifndef OS X#ifndef USG X#define USG X#endif X#endif X X#ifdef USG X#include X#include X#include X#include X#define OS "SYS III/V" X#define MODE2OK X#include X#endif X X#if HOWMANY > 255 XHowmany must be 255 or less X#endif X X/* X * return 1 iff stdout and stderr are different devices X * indicating this program operating with a modem on a X * different line X */ Xint Fromcu; /* Were called from cu or yam */ Xfrom_cu() X{ X struct stat a, b; X X fstat(1, &a); fstat(2, &b); X Fromcu = a.st_rdev != b.st_rdev; X return; X} Xcucheck() X{ X if (Fromcu) X fprintf(stderr,"Please read the manual page BUGS chapter!\r\n"); X} X X Xstruct { X unsigned baudr; X int speedcode; X} speeds[] = { X 110, B110, X 300, B300, X/* 600, B600,*/ X 1200, B1200, X 2400, B2400, X 4800, B4800, X 9600, B9600, X/* 19200, EXTA,*/ X/* 38400, EXTB,*/ X 0, X}; X Xint Twostop; /* Use two stop bits */ X X X#ifndef READCHECK X#ifdef FIONREAD X#define READCHECK X/* X * Return non 0 iff something to read from io descriptor f X */ Xrdchk(f) X{ X static long lf; X X ioctl(f, FIONREAD, &lf); X return ((int) lf); X} X#endif X#ifdef SV X#define READCHECK X#include X Xchar checked = '\0' ; X/* X * Nonblocking I/O is a bit different in System V, Release 2 X */ Xrdchk(f) X{ X int lf, savestat; X X savestat = fcntl(f, F_GETFL) ; X fcntl(f, F_SETFL, savestat | O_NDELAY) ; X lf = read(f, &checked, 1) ; X fcntl(f, F_SETFL, savestat) ; X return(lf) ; X} X#endif X#endif X X Xstatic unsigned Xgetspeed(code) X{ X register n; X X for (n=0; speeds[n].baudr; ++n) X if (speeds[n].speedcode == code) X return speeds[n].baudr; X return 38400; /* Assume fifo if ioctl failed */ X} X X X X#ifdef ICANON Xstruct termio oldtty, tty; X#else Xstruct sgttyb oldtty, tty; Xstruct tchars oldtch, tch; X#endif X Xint iofd = 0; /* File descriptor for ioctls & reads */ X X/* X * mode(n) X * 3: save old tty stat, set raw mode with flow control X * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g X * 1: save old tty stat, set raw mode X * 0: restore original tty mode X */ Xmode(n) X{ X static did0 = FALSE; X X vfile("mode:%d", n); X switch(n) { X#ifdef USG X case 2: /* Un-raw mode used by sz, sb when -g detected */ X if(!did0) X (void) ioctl(iofd, TCGETA, &oldtty); X tty = oldtty; X X tty.c_iflag = BRKINT|IXON; X X tty.c_oflag = 0; /* Transparent output */ X X tty.c_cflag &= ~PARENB; /* Disable parity */ X tty.c_cflag |= CS8; /* Set character size = 8 */ X if (Twostop) X tty.c_cflag |= CSTOPB; /* Set two stop bits */ X X X#ifdef READCHECK X tty.c_lflag = Zmodem ? 0 : ISIG; X tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */ X#else X tty.c_lflag = ISIG; X tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */ X#endif X tty.c_cc[VQUIT] = -1; /* Quit char */ X#ifdef NFGVMIN X tty.c_cc[VMIN] = 1; X#else X tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */ X#endif X tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ X X (void) ioctl(iofd, TCSETAW, &tty); X did0 = TRUE; X return OK; X case 1: X case 3: X if(!did0) X (void) ioctl(iofd, TCGETA, &oldtty); X tty = oldtty; X X tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK; X X /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */ X tty.c_lflag &= ~(ECHO | ICANON | ISIG); X X tty.c_oflag = 0; /* Transparent output */ X X tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */ X tty.c_cflag |= CS8; /* Set character size = 8 */ X if (Twostop) X tty.c_cflag |= CSTOPB; /* Set two stop bits */ X#ifdef NFGVMIN X tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */ X#else X tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */ X#endif X tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ X (void) ioctl(iofd, TCSETAW, &tty); X did0 = TRUE; X Baudrate = getspeed(tty.c_cflag & CBAUD); X return OK; X#endif X#ifdef V7 X /* X * NOTE: this should transmit all 8 bits and at the same time X * respond to XOFF/XON flow control. If no FIONREAD or other X * READCHECK alternative, also must respond to INTRRUPT char X * This doesn't work with V7. It should work with LLITOUT, X * but LLITOUT was broken on the machine I tried it on. X */ X case 2: /* Un-raw mode used by sz, sb when -g detected */ X if(!did0) { X /* ioctl(iofd, TIOCEXCL, 0);*/ X ioctl(iofd, TIOCGETP, &oldtty); X ioctl(iofd, TIOCGETC, &oldtch); X#ifdef LLITOUT X ioctl(TIOCLGET, &Locmode); /* Get "local mode" */ X#endif X } X tty = oldtty; X tch = oldtch; X#ifdef READCHECK X tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */ X#else X tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */ X#endif X tty.sg_flags |= (ODDP|EVENP|CBREAK); X/* tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);*/ X tty.sg_flags &= ~(CRMOD|ECHO); X ioctl(iofd, TIOCSETP, &tty); X ioctl(iofd, TIOCSETC, &tch); X#ifdef LLITOUT X ioctl(TIOCLBIS, &Locbit); X#endif X bibi(99); /* un-raw doesn't work w/o lit out */ X did0 = TRUE; X return OK; X case 1: X case 3: X if(!did0) { X/* ioctl(iofd, TIOCEXCL, 0);*/ X ioctl(iofd, TIOCGETP, &oldtty); X ioctl(iofd, TIOCGETC, &oldtch); X#ifdef LLITOUT X ioctl(TIOCLGET, &Locmode); /* Get "local mode" */ X#endif X } X tty = oldtty; X tty.sg_flags |= RAW; X tty.sg_flags &= ~ECHO; X ioctl(iofd, TIOCSETP, &tty); X did0 = TRUE; X Baudrate = getspeed(tty.sg_ospeed); X return OK; X#endif X case 0: X if(!did0) X return ERROR; X#ifdef USG X (void) ioctl(iofd, TCSBRK, 1); /* Wait for output to drain */ X (void) ioctl(iofd, TCFLSH, 1); /* Flush input queue */ X (void) ioctl(iofd, TCSETAW, &oldtty); /* Restore modes */ X (void) ioctl(iofd, TCXONC,1); /* Restart output */ X#endif X#ifdef V7 X ioctl(iofd, TIOCSETP, &oldtty); X ioctl(iofd, TIOCSETC, &oldtch); X/* ioctl(iofd, TIOCNXCL, 0);*/ X#ifdef LLITOUT X ioctl(TIOCLSET, &Locmode); /* Restore "local mode" */ X#endif X#endif X X return OK; X default: X return ERROR; X } X} X Xsendbrk() X{ X#ifdef V7 X#ifdef TIOCSBRK X#define CANBREAK X sleep(1); X ioctl(iofd, TIOCSBRK, 0); X sleep(1); X ioctl(iofd, TIOCCBRK, 0); X#endif X#endif X#ifdef USG X#define CANBREAK X ioctl(iofd, TCSBRK, 0); X#endif X} X X/* End of rbsb.c */ END_OF_FILE if test 6735 -ne `wc -c <'rbsb.c'`; then echo shar: \"'rbsb.c'\" unpacked with wrong size! fi # end of 'rbsb.c' fi if test -f 'zmodem.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'zmodem.h'\" else echo shar: Extracting \"'zmodem.h'\" \(5487 characters\) sed "s/^X//" >'zmodem.h' <<'END_OF_FILE' X/* X * Z M O D E M . H Manifest constants for ZMODEM X * application to application file transfer protocol X * 05-23-87 Chuck Forsberg Omen Technology Inc 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 Xlong rclhdr(); X X/* Globals used by ZMODEM functions */ Xextern Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */ Xextern Rxtype; /* Type of header received */ Xextern Rxcount; /* Count of data bytes received */ Xextern Zrwindow; /* RX window size (controls garbage count) */ Xextern Rxtimeout; /* Tenths of seconds to wait for something */ Xextern char Rxhdr[4]; /* Received header */ Xextern char Txhdr[4]; /* Transmitted header */ Xextern long Rxpos; /* Received file position */ Xextern long Txpos; /* Transmitted file position */ Xextern Txfcs32; /* TURE means send binary frames with 32 bit FCS */ Xextern Crc32t; /* Display flag indicating 32 bit CRC being sent */ Xextern Crc32; /* Display flag indicating 32 bit CRC being received */ Xextern Znulls; /* Number of nulls to send at beginning of ZDATA hdr */ Xextern char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */ X X/* End of ZMODEM.H */ END_OF_FILE if test 5487 -ne `wc -c <'zmodem.h'`; then echo shar: \"'zmodem.h'\" unpacked with wrong size! fi # end of 'zmodem.h' fi if test -f 'zterm.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'zterm.c'\" else echo shar: Extracting \"'zterm.c'\" \(5517 characters\) sed "s/^X//" >'zterm.c' <<'END_OF_FILE' X/* term - terminal simulator Author: Andy Tanenbaum */ X/* support for zmodem transfers and auto dialer added by X * bob best (bob@dhw68k.cts.com) X */ X/* This program allows the user to turn a MINIX system into a dumb X * terminal to communicate with a remote computer over a modem. It X * forks into two processes. The parent sits in a tight loop copying X * from the keyboard to the modem. The child sits in a tight loop X * copying from the modem to the screen. X * X * Example usage: X * term : 1200 baud, 8 bits/char, no parity X * term 9600 7 even : 9600 baud, 7 bits/char, even parity X * term odd 300 7 : 300 baud, 7 bits/char, odd parity X * X * The constant MODEM should be configured by the user X */ X#define MODEM "/dev/tty1" /* special file attached to the modem */ X#define ZDIR "/usr/lib/zterm" X#include X#include X#include X#include X X#define MAXARGS 3 /* maximum number of uart params */ X#define NCHECKS 10 X#define BAD -1 X#define GOOD 1 X#define DEF_SPEED B2400 /* default baudrate */ X#define DEF_BITS BITS8 /* default bits/char */ X#define TILDE '~' X#define CHUNK 1024 /* how much to read at once */ X Xint modem, pid; /* file descriptor for modem */ Xchar *pat[NCHECKS] = X{ X "5", "6", "7", "8", "110", "300", "1200", "2400", "4800", "9600"}; X Xint value[NCHECKS] = X{ X BITS5, BITS6, BITS7, BITS8, B110, B300, B1200, B2400, B4800, B9600}; X Xint hold[MAXARGS]; Xstruct sgttyb sgtty, sgsave1, sgsave2; Xjmp_buf jbuf; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X X sync(); X modem = open(MODEM, 2); X if (modem < 0) { X printf("Can't open modem on %s\n", MODEM); X exit(1); X } X setjmp(jbuf); X set_uart(argc, argv); X /* Main body of the terminal simulator. */ X if ( (pid = fork())) X copy(0, modem, 1); /* copy from stdin to modem */ X else X copy(modem, 1, -1); /* copy from modem to stdout */ X} X Xset_uart(argc, argv) Xint argc; Xchar *argv[]; X{ X /* Set up the UART parameters. */ X X int i, k, v, nspeeds = 0, speed, nbits = 0, bits, parity = 0; X X if (argc > MAXARGS + 1) X error("Usage: term [baudrate] [data_bits] [parity]\n"); X X /* Examine all the parameters and check for validity. */ X speed = DEF_SPEED; /* default line speed */ X bits = DEF_BITS; /* default bits/char */ X for (i = 1; i < argc; i++) { X if (strcmp(argv[i], "even") == 0) { X parity = EVENP; X continue; X } X if (strcmp(argv[i], "odd") == 0) { X parity = ODDP; X continue; X } X v = validity(argv[i]); X if (v == BAD) { X printf("Invalid parameter: %s\n", argv[i]); X exit(1); X } X k = atoi(argv[i]); X if (k > 100) { X speed = value[v]; X nspeeds++; X } X if ( k < 10) { X bits = value[v]; X nbits++; X } X if (nspeeds > 1) error("Too many speeds\n"); X if (nbits > 1) error("Too many character sizes\n"); X } X X /* Fetch the modem parameters, save them, and set new ones. */ X ioctl(modem, TIOCGETP, &sgtty); X sgsave1 = sgtty; /* modem parameters */ X sgtty.sg_ispeed = speed; X sgtty.sg_ospeed = speed; X sgtty.sg_flags = RAW | parity | bits; X ioctl(modem, TIOCSETP, &sgtty); X sleep(1); X/* write(modem,"AT\r",3);*/ X X /* Fetch the keyboard parameters, save them, and set new ones. */ X ioctl(0, TIOCGETP, &sgtty); X sgsave2 = sgtty; /* modem parameters */ X sgtty.sg_flags = (sgtty.sg_flags & 01700) + RAW; X ioctl(0, TIOCSETP, &sgtty); X} X X Xint validity(s) Xchar *s; X{ X /* Check parameter for legality. */ X X int i; X X for (i = 0; i < NCHECKS; i++) { X if (strcmp(s, pat[i]) == 0) return(i); X } X return(BAD); X} X X Xcopy(in, out, end) Xint in, out, end; X{ X/* Copy from the keyboard to the modem or vice versa. If the end character X * is seen LIMIT times in a row, quit. For the traffic from the modem, the X * end character is -1, which cannot occur since the characters from the X * modem are unsigned integers in the range 0 to 255. X */ X X int t, count, rc, size; X char buf[CHUNK], tmpbuf[CHUNK], *p; X X if (end > 0) X size=1; X else X size=CHUNK; X X while (1) { X if ( (count = read(in, buf, size)) < 0) { X printf("Can't read from modem\r\n"); X kill_child(); X mdm_restore(); X kbd_restore(); X exit(0); X } X X if (end > 0) { X t = buf[0] & 0377; /* t is unsigned int 0 - 255 */ X if (t == TILDE) { X count=read(in,buf,1); X t = buf[0] & 0377; X switch (t) { X case '.': X kill_child(); X mdm_restore(); X kbd_restore(); X printf("End of terminal session\r\n"); X exit(0); X case 'd': X kill_child(); X kbd_restore(); X strcpy(buf,ZDIR); X strcat(buf,"/dialer "); X strcat(buf,MODEM); X if (system(buf)) X exit(0); X mdm_restore(); X longjmp(jbuf,0); X break; X case 't': X kbd_restore(); X kill_child(); X strcpy(buf,ZDIR); X strcat(buf,"/bgzmod "); X puts("\r\nEnter file transfer command (rz or sz):"); X fflush(stdout); X gets(tmpbuf); X strcat(buf,tmpbuf); X strcat(buf," "); X if (!strcmp(tmpbuf,"sz")) { X puts("Enter files to send:"); X fflush(stdout); X gets(tmpbuf); X strcat(buf,tmpbuf); X } X strcat(buf," <"); X strcat(buf,MODEM); X strcat(buf," >"); X strcat(buf,MODEM); X strcat(buf," &"); X system(buf); X printf("\r\nReturning to shell\r\n"); X fflush(stdout); X exit(0); X/* mdm_restore();*/ X/* longjmp(jbuf,0);*/ X break; X case '~': X break; X default: X break; X X } X } X } X write(out, buf, count); X } X} X X Xerror(s) Xchar *s; X{ X printf("%s", s); X exit(1); X} X Xmdm_restore() X{ X ioctl(modem, TIOCSETP, &sgsave1); X} X Xkbd_restore() X{ X ioctl(0, TIOCSETP, &sgsave2); X} X Xkill_child() X{ X if (getpid() != pid) kill(pid, SIGINT); X} END_OF_FILE if test 5517 -ne `wc -c <'zterm.c'`; then echo shar: \"'zterm.c'\" unpacked with wrong size! fi # end of 'zterm.c' fi echo shar: End of archive 1 \(of 5\). >ark1isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Bob Best uucp: {spsd, zardoz, felix}!dhw68k!bob InterNet: bob@dhw68k.cts.com