koreth@ssyx.ucsc.edu (Steven Grimm) (05/30/88)
Submitted-by: bammi@mandrill.ces.cwru.edu (Jwahar R. Bammi) Posting-number: Volume 1, Issue 41 Archive-name: zmdm/part01 #!/bin/sh # shar: Shell Archiver (v1.22) # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # Run the following text with /bin/sh to create: # COMMON.C # COMMON.H # CONFIG.H # DECL.H # EXPANDAR.C # FILEIO.C # HI5025.S # LNK # MAIN.C # MAKEFALC.STA # MAKEFILE # MAKEFILE.ALC # MAKEFILE.MAN # MAKEFILE.STA # MAKEFMAN.STA # MANX.ASM # PHONE.C # RZ.C # RZLNK # SZ.C # SZLNK # TRANSFER.C # TYME.C # UTIL.C # YMODEM.DOC # ZM.C # ZMDM.DOC # ZMDM.H # ZMODEM.H # if test -r s2_seq_.tmp then echo "Must unpack archives in sequence!" next=`cat s2_seq_.tmp`; echo "Please unpack part $next next" exit 1; fi echo "x - extracting COMMON.C (Text)" sed 's/^X//' << 'SHAR_EOF' > COMMON.C && X/* X * ACKNOWLEDGEMENTS X * X * ZMDM was derived from rz/sz for Unix posted by X * Chuck Forsberg (...!tektronix!reed!omen!caf ). We X * thank him for his excellent code, and for giving X * us permission to use and distribute his code and X * documentation. X * X * Atari St version by: X * Jwahar Bammi X * usenet: mandrill!bammi@{decvax,sun}.UUCP X * csnet: bammi@mandrill.ces.CWRU.edu X * arpa: bammi@mandrill.ces.CWRU.edu X * CompuServe: 71515,155 X */ X X#include "config.h" X X#define IN_COMMON X X/* X * -rev 08-17-86 X * mode function and most of the rest of the system dependent X * stuff for rb.c and sb.c This file is #included so the includer X * can set parameters such as HOWMANY. See the main file (rz.c/sz.c) X * for compile instructions. X */ X X#ifdef DLIBS X#include <string.h> X#endif X X#include "zmdm.h" X#include "zmodem.h" X X#ifndef Supexec X /* Some versions of osbind don't define Supexec */ X#define Supexec(X) xbios(38,X) X#endif X X#define CRCTABLE X X /* GLOBALS */ Xint Zmodem; /* ZMODEM protocol requested */ Xint Nozmodem; /* If invoked as "rb" */ Xint Badclose; /* Error on last close */ Xint Batch; Xint Wcsmask; Xint Verbose; Xint Quiet; /* overrides logic that would otherwise set verbose */ Xint Lleft; /* number of characters in linbuf */ Xint Readnum; /* Number of bytes to ask for in read() from modem */ Xint Crcflg; Xint ForceBinary; /* local binary force override for rz */ X XFILE *logf; XFILE *STDERR; Xint vdebug; /* set if RDEBUG or SDEBUG */ X Xchar secbuf[KSIZE]; Xchar linbuf[KSIZE]; X#if (MWC || MANX) /* File i/o buffer */ Xunsigned char *bufr; /* In MWC or MANX it is lmalloc()'ed in main.c */ X#else X#ifndef DYNABUF Xunsigned char bufr[BBUFSIZ]; X#else Xunsigned char *bufr; X#endif /* DYNABUF */ X#endif Xint fout; Xint Lastrx; Xint Firstsec; Xint Eofseen; /* indicates cpm eof (^Z) has been received */ Xint errors; Xlong Bytesleft; /* number of bytes of incoming file left */ Xlong Modtime; /* Unix style mod time for incoming file */ Xint Filemode; /* Unix style mode for incoming file */ Xchar Pathname[PATHLEN]; Xchar *Progname; /* the name by which we were called */ X Xint Thisbinary; /* current file is to be received in bin mode */ Xint Blklen; /* record length of received packets */ Xchar Lzmanag; /* Local file management request */ Xchar zconv; /* ZMODEM file conversion request */ Xchar zmanag; /* ZMODEM file management request */ Xchar ztrans; /* ZMODEM file transport request */ X Xjmp_buf tohere; /* For the interrupt on RX timeout */ Xjmp_buf abrtjmp; /* for force abort */ Xjmp_buf busjmp; /* for bus errors */ Xjmp_buf addrjmp; /* for address errors */ Xunsigned long BusErr, AddrErr; /* saved vector addresses */ Xint Zctlesc; /* Encode control characters */ Xint SendType; /* Which send line to use */ Xint Modem; /* Send using Xmodem */ Xint lsct; Xint tryzhdrtype; /* Header type to send corresponding to Last rx close */ Xint Txfcs32; /* TRUE means send binary frames with 32 bit FCS */ X X /* Globals used by ZMODEM functions */ Xint Rxframeind; /* ZBIN or ZHEX indicates type of frame received */ Xint Rxtype; /* Type of header received */ Xint Rxcount; /* Count of data bytes received */ Xint Rxtimeout; /* Tenths of seconds to wait for something */ Xint Znulls; /* Number of nulls to send at beginning of ZDATA hdr */ Xchar Rxhdr[4]; /* Received header */ Xchar Txhdr[4]; /* Transmitted header */ Xlong Rxpos; /* Received file position */ Xlong Txpos; /* Transmitted file position */ Xchar Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */ X X /* Globals used by Sz */ Xchar Lzconv; /* Local ZMODEM file conversion request */ Xchar Lztrans; Xchar *Cmdstr; /* Pointer to the command string */ Xint Optiong; /* Let it rip no wait for sector ACK's */ Xint Noeofseen; Xint Totsecs; /* total number of sectors this file */ Xint Command; /* Send a command, then exit. */ Xint Cmdack1; /* Rx ACKs command, then do it */ Xint Exitcode; Xint Testattn; /* Force receiver to send Attn, etc with qbf. */ Xint Lastc; /* Count of last buffer read or -1 */ Xint Dontread; /* Don't read the buffer, it's still there */ Xint Wantfcs32; /* want to send 32 bit FCS */ Xlong Lastread; /* Beginning offset of last buffer read */ Xjmp_buf intrjmp; /* For the interrupt on RX CAN */ X Xchar *qbf; Xunsigned int Rxbuflen; /* Receiver's max buffer length */ Xint Cmdtries; Xint Filcnt; /* count of number of files opened */ Xint Lfseen; Xint Tframlen; /* Override for tx frame length */ Xint blkopt; /* Override value for zmodem blklen */ Xint Rxflags; Xint Ascii; /* Add CR's for brain damaged programs */ Xint Fullname; /* transmit full pathname */ Xint Unlinkafter; /* Unlink file after it is sent */ Xint Dottoslash; /* Change foo.bar.baz to foo/bar/baz */ Xint errcnt; /* number of files unreadable */ Xint siggi; /* line interrupt enable flag */ X X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */ Xunsigned int crctab[256] = { 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 * Copyright (C) 1986 Gary S. Brown. You may use this program, or X * code or tables extracted from it, as desired without restriction. X * X * Need an unsigned type capable of holding 32 bits; X */ Xtypedef unsigned long int UNS_32_BITS; X X/* First, the polynomial itself and its table of feedback terms. The */ X/* polynomial is */ X/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ X/* Note that we take it "backwards" and put the highest-order term in */ X/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ X/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ X/* the MSB being 1. */ X X/* Note that the usual hardware shift register implementation, which */ X/* is what we're using (we're merely optimizing it by doing eight-bit */ X/* chunks at a time) shifts bits into the lowest-order term. In our */ X/* implementation, that means shifting towards the right. Why do we */ X/* do it this way? Because the calculated CRC must be transmitted in */ X/* order from highest-order term to lowest-order term. UARTs transmit */ X/* characters in order from LSB to MSB. By storing the CRC this way, */ X/* we hand it to the UART in the order low-byte to high-byte; the UART */ X/* sends each low-bit to hight-bit; and the result is transmission bit */ X/* by bit from highest- to lowest-order term without requiring any bit */ X/* shuffling on our part. Reception works similarly. */ X X/* The feedback terms table consists of 256, 32-bit entries. Notes: */ X/* */ X/* The table can be generated at runtime if desired; code to do so */ X/* is shown later. It might not be obvious, but the feedback */ X/* terms simply represent the results of eight shift/xor opera- */ X/* tions for all combinations of data and CRC register values. */ X/* */ X/* The values must be right-shifted by eight bits by the "updcrc" */ X/* logic; the shift must be unsigned (bring in zeroes). On some */ X/* hardware you could probably optimize the shift in assembler by */ X/* using byte-swap instructions. */ X Xunsigned long int crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ X 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, X 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, X 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, X 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, X 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, X 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, X 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, X 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, X 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, X 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, X 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, X 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, X 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, X 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, X 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, X 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, X 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, X 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, X 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, X 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, X 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, X 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, X 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, X 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, X 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, X 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, X 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, X 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, X 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, X 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, X 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, X 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, X 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, X 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, X 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, X 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, X 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, X 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, X 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, X 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, X 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, X 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, X 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, X 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, X 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, X 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, X 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, X 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, X 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, X 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, X 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, X 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, X 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, X 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, X 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, X 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, X 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, X 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, X 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, X 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, X 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, X 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, X 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, X 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL X}; X X#ifndef REMOTE Xint *aline_addr; /* Base addr of aline variables */ X#endif X Xint hlines = 25; /* # of lines on screen */ Xint rez; /* current resolution */ Xint scolor = 0; /* current fg/bg screen color toggle */ X X#ifndef REMOTE Xlong *ms_ptr; /* Pointer to my screen memory, aligned at X a 256 bytes boundary */ X#endif /* REMOTE */ X X#if (!(MWC || MANX)) X#ifndef REMOTE Xlong m_screen[8*1024+32]; /* My screen memory X 32K bytes + 256 Bytes guard for alignement X In the worst case when we align we have to X go 255 bytes from &m_screen[0], hence the X 256 Byte guard is required */ X#endif /* REMOTE */ X X#else /* MWC || MANX */ X X#ifdef RECURSE X#ifdef BIGSTACK X#ifdef MWC Xlong _stksize = 128L * 1024L; X#else Xlong _STKSIZ = 128L * 1024L; X#endif X#else X#ifdef MWC Xlong _stksize = 16L * 1024L; X#else Xlong _STKSIZ = 16L * 1024L; X#endif X#endif /* BIGSTACK */ X#else X#ifdef MWC Xlong _stksize = 16384L; X#else Xlong _STKSIZ = 16384L; X#endif X#endif /* RECURSE */ X X#ifndef REMOTE Xlong *m_screen; /* Presently Mark Willams will not allow X > 32K static structures */ X#endif /* REMOTE */ X X#endif /* MWC */ X X#ifdef DLIBS X#ifdef RECURSE X#ifdef BIGSTACK Xlong _STKSIZE = 128L * 1024L; X#else Xlong _STKSIZE = 16L * 1024L; X#endif /* BIGSTACK */ X#else Xlong _STKSIZE = 16384L; X#endif /* RECURSE */ X#endif /* DLIBS */ X Xstruct stat statbuf; /* Disk Transfer address for Find first etc */ Xint Baudrate; /* Current baud rate */ Xlong drv_map; /* bit vector of valid drives */ X XBAUDS vbauds[] = { X { "19200", 0, 19200 }, X { "9600" , 1, 9600 }, X { "4800" , 2, 4800 }, X { "4800" , 2, 4800 }, X { "2400" , 4, 2400 }, X { "2400" , 4, 2400 }, X { "2400" , 4, 2400 }, X { "1200" , 7, 1200 }, X { "1200" , 7, 1200 }, X { "300" , 9, 300 }, X { (char *)NULL, -1, -1 } X}; X XIOREC save, /* the original Iorec is saved here for the duration of this X process */ X *savep; /* ptr returned by Iorec() */ X Xchar iobuf[IBUFSIZ]; /* My large Rs232 receive buffer */ X X#ifdef DYNABUF Xlong BBUFSIZ; X#endif /* DYNABUF */ X Xextern long pr_time; X X /* statics */ Xstatic char *tsr_ptr = (char *)0x00fffa2dL; /* See St internals */ Xstatic long *hz_200 = (long *)0x000004ba; /* Yes the Hitch Hikers */ X /* Guide is wrong!! */ X Xstatic long X alrm_time = 0L; /* Time of next timeout (200 Hz) */ X Xstatic char *special[] = { X".PRG", ".TOS", ".TTP", ".ARC", ".ACC", ".IMG", ".RSC", ".O", X".OBJ", ".NEO", X".PIC", ".PI1", ".PI2", ".PI3", ".PQ1", ".PQ2", ".PQ3", ".BRD", X".ANI", ".STW", X".FNT", ".PRT", ".SNG", ".NEC", ".CNF", ".Z" , ".DFN", ".GEM", X".EZD", ".LNK", X".SYM", ".DVI", ".PIX", ".X32", ".OUT", ".A", ".CCC", ".CL", X".CMD", ".COM", X".CRL", ".DAT", ".DIR", ".EXE", ".OVL", ".PAG", ".REL", ".SAV", X".SUB", ".SWP", X".SYS", ".TAR", ".UTL", ".BIN", ".LBR", ".IM", ".PAK", X".SBM", ".OBM", ".DIC", ".NDX", ".TFM", ".PBM", ".PBP", ".PCC", X".PXL", X"" X}; X X/* X * mode(n) X * 2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g X option X * 1: save old tty stat, set raw mode X * 0: restore original tty mode X */ Xmode(n) X{ X X vfile("mode:%d", n); X switch(n) { X X case 2: /* Cbreak mode used by sb when -g detected */ X return OK; X case 1: X return OK; X case 0: X while(Bconstat(1)) Bconin(1); /* flush input */ X X return OK; X default: X return ERROR; X } X} X X/* X * send a break X * Modifies Bit 3 in the TSR (reg 23) of the Mfp X */ X Xsendbrk() X{ X register long save_ssp; X register long time; X X save_ssp = Super(0L); /* Super Mode */ X X /* set bit 3 of the TSR */ X *tsr_ptr |= (char)8; X X X /* wait for 250 ms */ X time = *hz_200 + 50; X while(*hz_200 < time) X /* wait */ ; X X /* reset bit 3 of the tsr */ X *tsr_ptr &= (char)~8; X X Super(save_ssp); /* Back to user Mode */ X} X X#ifdef TX X/* X * Put transmit section of the MFP uart off X * X */ XTxoff() X{ X register long save_ssp; X X save_ssp = Super(0L); /* Super Mode */ X X /* clear bit 0 of the tsr */ X *tsr_ptr &= (char)~1; X X Super(save_ssp); /* Back to user Mode */ X} X X/* X * Put transmit section of the MFP uart on X * X */ XTxon() X{ X register long save_ssp; X X save_ssp = Super(0L); /* Super Mode */ X X /* set bit 0 of the tsr */ X *tsr_ptr |= (char)1; X X Super(save_ssp); /* Back to user Mode */ X} X#endif /* TX */ X X X/* X * read_modem() - read upto count characters from the modem port X * Check for user abort (^C) and timeout at the same time X */ Xint read_modem(buf, count) Xregister char *buf; Xregister int count; X{ X register int n; X extern void rd_time(); X X n = 0; X X while(1) X { X#ifndef REMOTE X if(Bconstat(2)) X { X /* Character Hit at the Keyboard - is it ^C */ X if((Bconin(2) & 0x7f) == CTRL('C')) X { X /* It is a Control-C */ X if(SendType) X bibis(3); X else X bibi(3); X } X X } X#endif X if(Bconstat(1)) X { X /* Character available at Modem Port */ X n++; X *buf++ = Bconin(1); X X while((n < count) && Bconstat(1)) X { X *buf++ = Bconin(1); X n++; X X } X return n; X } X X /* Check for time out if required */ X if(alrm_time != 0) X { X /* Alarm Set */ X Supexec(rd_time); X if(pr_time >= alrm_time) X /* timeout */ X longjmp(tohere, -1); X } X } X} X X X/* X * alarm() - set the alarm time X */ Xvoid stalarm(n) Xunsigned int n; X{ X extern void rd_time(); X X if(n > 0) X { X Supexec(rd_time); X /* We really need n * 200 but n * 256 is close enough */ X alrm_time = pr_time + ( n << 8 ); X } X else X alrm_time = 0L; X} X X/* X * write_modem() - send buffer to the modem port X * X*/ Xvoid write_modem(buf,len) Xregister char *buf; Xregister int len; X{ X register int i; X for(i = 0; i < len; i++) X Bconout(1, *buf++); X} X X X/* X * flushinput() - flush any characters in the modem port X * a future enhancement may be flush any characters that are in there X * and any that come in over the next 1 second -- Ymodem does that X * X */ Xvoid flushinput() X{ X while(Bconstat(1)) X Bconin(1); X} X X X Xint isbinary(name) Xregister char *name; X{ X register char **p; X register char *ext; X extern char *rindex(); X extern int ustrcmp(); X X if((ext = rindex(name,'.')) == (char *)NULL) X { X return 0; X } X X for(p = special; **p != '\0'; p++) X if(ustrcmp(ext,*p) == 0) X return 1; X return 0; X} X X#define upper(X) (islower(X)?toupper(X):X) X X/* Strcmp - case insensative */ Xint ustrcmp(s1,s2) Xregister char *s1, *s2; X{ X while(*s1 != '\0') X { X if(*s2 == '\0') X return 1; X if(upper(*s1) != *s2) X return 1; X s1++; X s2++; X } X if(*s2 != '\0') X return 1; X else X return 0; X} X X X/* X * Ensure that each subdirectory in the pathname exists. X * If one doesn'nt, make the rest of the directory X * Returns ERROR if it has trouble creating a path X * X */ Xint pathensure(name) Xchar *name; X{ X extern char *index(); X X if(index(name, '\\') == (char *)NULL) X /* nothing to check */ X return OK; X X return pathrest(name, (char *)NULL); X} X X/* X * check rest of the path recursively X * If any component of the path name is longer than 8/12 characters then X * warn. X * X */ Xint pathrest(name, prev) Xchar *name, *prev; X{ X char previous[128]; X char component[13]; X register char *p, *q, *r, *s; X register int warn; X extern char *index(); X extern char *in(); X X if((r = index(name, '\\')) == (char *)NULL) X /* nothing more to check */ X return OK; X X /* pick up the next component of the path name, 8/12 chars max for ST */ X warn = 0; X if((s = in(name, r, '.')) == (char *)NULL) X { X /* component does'nt contain a dot */ X if( ((long)r - (long)name) > 8) X { X warn++; X strncpy(component, name, 8); X q = &component[8]; X } X else X { X register int n; X X n = (int)((long)r - (long)name); X strncpy(component, name, n); X component[n] = '\0'; X q = &component[(strlen(component))]; X } X } X else X { X /* component contains a dot */ X if(((long)s - (long)name) > 8) X { X warn++; X strncpy(component, name, 8); X q = &component[8]; X } X else X { X for(p = name, q = component; p != s; ) X *q++ = *p++; X } X *q++ = '.'; X s++; X if(s != r) X { X if(((long)r - (long)s) > 3) X { X warn++; X strncpy(q, s, 3); X q = &q[3]; X } X else X { X for(p = s; p != r; ) X *q++ = *p++; X } X } X } X *q = '\0'; X X#ifndef REMOTE X if(warn) X { X fprintf(stderr, X "?WARNING - A component of the path is longer than 8/12 chars\n"); X fprintf(stderr,"%s --> %s\n", name, component); X } X#endif X if(prev == (char *)NULL) X strcpy(previous, component); X else X { X strcpy(previous, prev); X strcat(previous, "\\"); X strcat(previous, component); X } X X if(existd(previous)) X /* it exists - go do rest */ X return pathrest(++r, previous); X X /* does not exist, */ X /* make this component and all its children */ X return makesubtree(++r, previous); X} X X/* X * make a subtree X */ Xint makesubtree(name, prev) Xchar *name, *prev; X{ X char previous[128]; X char component[13]; X register char *p, *q, *r, *s; X register int warn; X extern char *index(); X extern char *in(); X X if(Dcreate(prev) != 0) X { X log2("Trouble trying to create subtree\n"); X fprintf(STDERR,"%s\n", prev); X return ERROR; X } X#ifndef REMOTE X fprintf(stderr,"Created Directory %s\n", prev); X#endif X if((r = index(name, '\\')) == (char *)NULL) X /* nothing more to do */ X return OK; X X /* pick up the next component of the path name, 8/12 chars max for ST */ X warn = 0; X if((s = in(name, r, '.')) == (char *)NULL) X { X /* component does'nt contain a dot */ X if( ((long)r - (long)name) > 8) X { X warn++; X strncpy(component, name, 8); X q = &component[8]; X } X else X { X register int n; X X n = (int)((long)r - (long)name); X strncpy(component, name, n); X component[n] = '\0'; X q = &component[(strlen(component))]; X } X } X else X { X /* component contains a dot */ X if(((long)s - (long)name) > 8) X { X warn++; X strncpy(component, name, 8); X q = &component[8]; X } X else X { X for(p = name, q = component; p != s; ) X *q++ = *p++; X } X *q++ = '.'; X s++; X if(s != r) X { X if(((long)r - (long)s) > 3) X { X warn++; X strncpy(q, s, 3); X q = &q[3]; X } X else X { X for(p = s; p != r; ) X *q++ = *p++; X } X } X } X *q = '\0'; X X#ifndef REMOTE X if(warn) X { X fprintf(stderr, X "?WARNING - A component of the path is longer than 8/12 chars\n"); X fprintf(stderr,"%s --> %s\n", name, component); X } X#endif X strcpy(previous, prev); X strcat(previous, "\\"); X strcat(previous, component); X X X X /* go do the rest of them */ X return makesubtree(++r, previous); X} X X X/* X * test if a subdirectory exists X * include special case of 'D:\' that Fsfirst does'nt handle correctly X */ Xint existd(name) Xregister char *name; X{ X /* assuming the DTA buffer is already set up */ X extern long drv_map; X extern struct stat statbuf; X register int drive; X X if (Fsfirst(name , 0x0021|0x0010) == 0) X { X if((statbuf.st_mode & 0x0010) == 0x0010) X return TRUE; X } X X /* Gemdos doesn't like d:\ style dirs */ X if((name[3] == '\0') && (name[2] == '\\') && (name[1] == ':')) X { X drive = name[0]; X if(isupper(drive)) X drive = tolower(drive); X X drive = drive - 'a'; X if((drv_map & (1L << drive)) == 0) X return FALSE; X else X return TRUE; X } X /* Nor does Gemdos understand '.' or '..' */ X /* Hey Atari, don't you guys ever test anything */ X if((strcmp(name,".") == 0) || (strcmp(name,"..") == 0) || X (strcmp(name,".\\") == 0) || (strcmp(name,"..\\") == 0)) X return TRUE; X X return FALSE; X} X X/* X * Does a file exist X */ Xint existf(name) Xregister char *name; X{ X /* assuming the DTA buffer is already set up */ X X return (Fsfirst(name , 0x0001) == 0); X X} X X/* X * stsystem(cmd) - execute a process X * char *cmd; command to execute (including redirections etc) X */ Xint stsystem(cmd) Xchar *cmd; X{ X register char *ptr1; /* general pointers */ X register char save; /* */ X register int status; /* return status */ X register char *args; /* arguments */ X register int len; /* length of args - 2 */ X char nils[2]; X extern char *malloc(); X X X nils[0] = nils[1] = '\0'; X for(ptr1 = cmd; (!isspace(*ptr1)) && (*ptr1 != '\0'); ptr1++) X /* skip till end of path name */; X if(*ptr1 != '\0') X { X /* cmd does have a command tail */ X /* save the char at the position and terminate the path */ X save = *ptr1; X *ptr1++ = '\0'; /* command tail is the rest of it */ X X if((args = (char *) malloc((len = strlen(ptr1)) + 2)) X == (char *)NULL) X { X /* could not allocate memory */ X return(-1); X } X *args++ = len; X strcpy(args,ptr1); X args--; X /* now do the load and go */ X status = Pexec(0,cmd,args,(char *)NULL); X /* restore cmd to original state */ X *--ptr1 = save; X free(args); X } X else X { X /* command does not have a tail */ X X /* now do the load and go */ X status = Pexec(0,cmd,nils,(char *)NULL); X } X X return(status); X} X Xstsleep(n) Xint n; X{ X extern void rd_time(); X X if(n != 0) X { X Supexec(rd_time); X /* We really need n * 200 but n * 256 if close enough */ X alrm_time = pr_time + ( n << 8 ); X X while(alrm_time > pr_time) X { X Supexec(rd_time); X } X alrm_time = 0L; X } X} X X Xinitz() X{ X Zmodem=0; /* ZMODEM protocol requested */ X Nozmodem = 0; /* If invoked as "rb" */ X Badclose = 0; /* Error on last close */ X Batch=0; X Wcsmask=0377; X Verbose=0; X lsct = 1; X Quiet=0; /* overrides logic that would otherwise set verbose */ X Lleft=0; /* number of characters in linbuf */ X X logf = (FILE *)NULL; X vdebug = 0; X X Readnum = KSIZE; /* Number of bytes to ask for in read() from modem */ X Crcflg = FALSE; X fout = (-1); X errors = 0; X Rxtimeout = 100; /* Tenths of seconds to wait for something */ X Modem = 0; X Blklen = SECSIZ; /* record length of received packets */ X X qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n"; X Cmdtries = 11; X Filcnt=0; /* count of number of files opened */ X Lfseen=0; X Rxbuflen = 1024; /* Receiver's max buffer length */ X Tframlen = 0; /* Override for tx frame length */ X blkopt=0; /* Override value for zmodem blklen */ X Rxflags = 0; X Ascii=0; /* Add CR's for brain damaged programs */ X Fullname=0; /* transmit full pathname */ X Unlinkafter=0; /* Unlink file after it is sent */ X Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */ X errcnt=0; /* number of files unreadable */ X Testattn = FALSE; X siggi = 0; X Command = FALSE; X Wantfcs32 = TRUE; /* want to send 32 bit FCS */ X Znulls = 0; X tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */ X Txfcs32 = FALSE; /* TRUE means send binary frames with 32 bit FCS */ X ForceBinary = FALSE; /* Local force binary override for rz */ X X} X X/* abort current session - due to async fault */ Xaexit(n) Xint n; X{ X longjmp(abrtjmp, n); X} X Xbuserr() X{ X longjmp(busjmp, -1); X} X Xaddrerr() X{ X longjmp(addrjmp, -1); X} X X/* X * Local console output simulation X */ Xbttyout(c) X{ X if (Verbose) X#ifdef REMOTE X Bconout(1, c); X#else X putc(c, stderr); X#endif X} X X/* X * Send a character to modem. Small is beautiful. X */ Xsendline(c) Xint c; X{ X#ifndef REMOTE X if (Verbose>4) X { X fprintf(stderr, "Sendline: %x\n", c); X X } X#endif X if (SendType) X Bconout(1, c & Wcsmask); X else X Bconout(1, c); X X} X X X X/* X * substr(string, token) searches for token in string s X * returns pointer to token within string if found, NULL otherwise X */ Xchar * Xsubstr(s, t) Xregister char *s; Xchar *t; X{ X register char *ss,*tt; X /* search for first char of token */ X for (ss=s; *s; s++) X if (*s == *t) X /* compare token with substring */ X for (ss=s,tt=t; ;) X { X if (*tt == '\0') X return s; X if (*ss++ != *tt++) X break; X } X X return ((char *)NULL); X} X X X/* send cancel string to get the other end to shut up */ Xcanit() X{ X static char canistr[] = { X ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0 X }; X X write_modem(canistr, strlen(canistr)); X if(!SendType) X Lleft=0; /* Do read next time ... */ X X} X X X/* X * Debugging information output interface routine X */ X/* VARARGS1 */ Xvfile(f, a, b, c) Xregister char *f; Xint a, b, c; X{ X if (Verbose > 3) X { /* verbose 2 is normal for us */ X fprintf(STDERR, f, a, b, c); X fprintf(STDERR, "\n"); X X if(vdebug && (logf != (FILE *)NULL)) X { X fprintf(logf, f, a, b, c); X fprintf(logf, "\n"); X fflush(logf); X } X X } X} X X/* longs and pointers are not integers */ X/* VARARGS1 */ Xvfile2(f, a, b, c) Xlong a, b, c; Xregister char *f; X{ X if (Verbose > 3) X { X fprintf(STDERR, f, a, b, c); X fprintf(STDERR, "\n"); X X if(vdebug && (logf != (FILE *)NULL)) X { X fprintf(logf, f, a, b, c); X fprintf(logf, "\n"); X fflush(logf); X } X X } X} X Xchar *in(from, to, c) Xregister char *from, *to; Xregister int c; X{ X for(; from < to; from++) X { X if(*from == c) X return from; X } X return (char *)NULL; X} X X/* X * SetIoBuf() - Save the systems Rs232 buffer and install my large X * Rs232 buffer. X * X */ Xvoid SetIoBuf() X{ X /* Get pointer to Rs232 input record */ X savep = (IOREC *)Iorec(0); X X /* Save the info */ X save.ibuf = savep->ibuf; X save.ibufsiz = savep->ibufsiz; X save.ibufhd = savep->ibufhd; X save.ibuftl = savep->ibuftl; X save.ibuflow = savep->ibuflow; X save.ibufhi = savep->ibufhi; X X /* Install my buffer in its place */ X savep->ibuf = &iobuf[0]; X savep->ibufsiz = IBUFSIZ; X savep->ibuflow = IBUFSIZ/4; X savep->ibufhi = (IBUFSIZ / 4) * 3; X savep->ibufhd = savep->ibuftl = 0; X X} X X/* X * ResetIoBuf() - Reset the Rs232 buffer to the saved (system's) buffer X * X */ Xvoid ResetIoBuf() X{ X savep->ibuf = save.ibuf; X savep->ibufsiz = save.ibufsiz; X savep->ibuflow = save.ibuflow; X savep->ibufhi = save.ibufhi; X savep->ibufhd = save.ibufhd; X savep->ibuftl = save.ibuftl; X} X X Xflush_modem() X{ X while(Bcostat(1) == 0); X} X X X X/* X * Log an error if verbose X */ X X/*VARARGS1*/ Xlog2(s,p,u) Xchar *s; Xint p, u; X{ X if (!Verbose) X return; X fprintf(STDERR, "\nerror %d: ", errors); X fprintf(STDERR, s, p, u); X X#ifdef RDEBUG X if(Verbose > 3) X { X fprintf(logf, "error %d: ", errors); X fprintf(logf, s, p, u); X } X#endif X X} X/* X * This version of readline is reasonably well suited for X * reading many characters. X * timeout is in tenths of seconds X */ Xint readline(timeout) Xint timeout; X{ X register int n; X static char *cdq; /* pointer for removing chars from linbuf */ X X if (--Lleft >= 0) X { X#ifdef RDEBUG X if (Verbose > 8) X { X fprintf(logf, "%02x ", *cdq&0377); X } X#endif X X return (*cdq++ & Wcsmask); X } X/* n = timeout/10; */ X n = timeout >> 3; /* close enough for rock and roll - see alarm() */ X if (n < 2) X n = 3; X#ifdef RDEBUG X if (Verbose > 3) X fprintf(logf, "Calling read: n=%d ", n); X#endif X X if (setjmp(tohere)) X { X Lleft = 0; X#ifdef RDEBUG X if (Verbose>3) X { X fprintf(STDERR, "Readline:TIMEOUT\n"); X fprintf(logf, "Readline:TIMEOUT\n"); X X } X#endif X return TIMEOUT; X } X stalarm(n); X Lleft=read_modem(cdq=linbuf, Readnum); X stalarm(0); X X#ifdef RDEBUG X if (Verbose > 3) X { X fprintf(logf, "Read returned %d bytes\n", Lleft); X } X#endif X X if (Lleft < 1) X return TIMEOUT; X --Lleft; X X#ifdef RDEBUG X if (Verbose > 8) X { X fprintf(logf, "%02x ", *cdq&0377); X } X#endif X X return (*cdq++ & Wcsmask); X} X Xreport(sct) Xint sct; X{ X#ifndef REMOTE X if (Verbose>1) X fprintf(STDERR,"%03d%c",sct,sct%10? ' ' : '\r'); X#endif X} X Xlreport(sct) Xlong sct; X{ X#ifndef REMOTE X if (Verbose>1) X fprintf(STDERR,"%06ld%c",sct,lsct%10? ' ' : '\r'); X lsct++; X#endif X} X X X#ifdef DLIBS X_initargs() X{ X} X#endif X Xwr_modem(s) Xregister char *s; X{ X while(*s != '\0') X Bconout(1, *s++); X} X X#ifdef DYNABUF Xunsigned char *dalloc() X{ X register long avail; X X if((avail = (long)Malloc(-1L) - LEAVEALONE) < MINACC) X return (unsigned char *)NULL; X X BBUFSIZ = avail; X return (unsigned char *)Malloc(BBUFSIZ); X} X#endif /* DYNABUF */ X X/* ******************************************************* X This code courtesy of katzung@laidbak.UUCP X -- thank you very much X ******************************************************* */ X X X/* From laidbak!katzung@Sun.COM Tue Apr 26 19:34:41 1988 XReturn-Path: <laidbak!katzung@Sun.COM> XFrom: Brian Katzung <laidbak!katzung@Sun.COM> XTo: bammi@mandrill.CES.CWRU.Edu XSubject: Re: UW X*/ X X#define MFP 0xFFFFFA01L X#define TDDR 36 X#define hz_200 ((unsigned long *) 0x4BAL) X X/* Baud rates 75 (120) and 50 (80) are not currently decoded. */ Xstatic int timevals[] = { X 1, 2, 4, 5, 8, 10, 11, X 16, 32, 64, 96, 128, 143, 175 X}; X X X/* load rs232 baud rate, returns -1 if not known */ Xint getbaud () X{ X register int i; X int tv; /* Timer value */ X int maxtv; /* Maximum timer value */ X unsigned long endhz; /* End of polling period */ X long savessp; /* Old stack pointer */ X X savessp = Super(0L); X maxtv = 0; X endhz = *hz_200 + 8; X while (*hz_200 < endhz) X { X tv = *((unsigned char *) (MFP + TDDR)); X if (tv > maxtv) X maxtv = tv; X } X (void) Super(savessp); X for (i = sizeof(timevals) / sizeof(timevals[0]); X --i >= 0 && timevals[i] != maxtv; ); X if (i >= 0) X return(i); X return(-1); X} X X/* -eof- */ SHAR_EOF chmod 0600 COMMON.C || echo "restore of COMMON.C fails" echo "x - extracting COMMON.H (Text)" sed 's/^X//' << 'SHAR_EOF' > COMMON.H && X/* X * Common include file X * X * Jwahar Bammi X * usenet: mandrill!bammi@{decvax,sun}.UUCP X * csnet: bammi@mandrill.ces.CWRU.edu X * arpa: bammi@mandrill.ces.CWRU.edu X * CompuServe: 71515,155 X */ X Xextern int Zmodem; /* ZMODEM protocol requested */ Xextern int Nozmodem; /* If invoked as "rb" */ Xextern int Badclose; /* Error on last close */ Xextern int Batch; Xextern int Wcsmask; Xextern int Verbose; Xextern int Quiet; /* overrides logic that would otherwise set verbose */ Xextern int Lleft; /* number of characters in linbuf */ Xextern int Readnum; /* Number of bytes to ask for in read() from modem */ Xextern int Crcflg; Xextern int ForceBinary; /* local binary force override for rz */ Xextern char secbuf[]; Xextern char linbuf[]; X#if (MWC || MANX) /* File i/o buffer */ Xextern unsigned char *bufr; X#else X#ifndef DYNABUF Xextern unsigned char bufr[]; X#else Xextern unsigned char *bufr; X#endif X#endif Xextern int fout; Xextern int Lastrx; Xextern int Firstsec; Xextern int Eofseen; /* indicates cpm eof (^Z) has been received */ Xextern int errors; Xextern long Bytesleft; /* number of bytes of incoming file left */ Xextern long Modtime; /* Unix style mod time for incoming file */ Xextern int Filemode; /* Unix style mode for incoming file */ Xextern char Pathname[]; Xextern char *Progname; /* the name by which we were called */ Xextern int Zctlesc; /* Encode control characters */ Xextern int SendType; /* Which send line to use */ X Xextern int Thisbinary; /* current file is to be received in bin mode */ Xextern int Blklen; /* record length of received packets */ Xextern char Lzmanag; /* Local file management request */ Xextern char zconv; /* ZMODEM file conversion request */ Xextern char zmanag; /* ZMODEM file management request */ Xextern char ztrans; /* ZMODEM file transport request */ Xextern jmp_buf tohere; /* For the interrupt on RX timeout */ Xextern jmp_buf busjmp; /* for bus errors */ Xextern jmp_buf addrjmp; /* for address errors */ Xextern unsigned long BusErr, AddrErr; /* saved vector addresses */ Xextern int buserr(); /* Bus error handler */ Xextern int addrerr(); /* address error handler */ Xextern int Modem; /* Send using Xmodem */ Xextern FILE *logf; Xextern FILE *STDERR; Xextern int vdebug; Xextern int lsct; Xextern int tryzhdrtype; /* Header type to send corresponding to Last rx close */ Xextern int Txfcs32; /* TRUE means send binary frames with 32 bit FCS */ X X /* Globals used by ZMODEM functions */ Xextern int Rxframeind; /* ZBIN or ZHEX indicates type of frame received */ Xextern int Rxtype; /* Type of header received */ Xextern int Rxcount; /* Count of data bytes received */ Xextern int Rxtimeout; /* Tenths of seconds to wait for something */ Xextern char Rxhdr[]; /* Received header */ Xextern char Txhdr[]; /* Transmitted header */ Xextern long Rxpos; /* Received file position */ Xextern long Txpos; /* Transmitted file position */ Xextern char Attn[]; /* Attention string rx sends to tx on err */ X X /* Globals specific to Sz */ Xextern int Baudrate; Xextern int Ascii; /* Add CR's for brain damaged programs */ Xextern int Fullname; /* transmit full pathname */ Xextern int Unlinkafter; /* Unlink file after it is sent */ Xextern int Dottoslash; /* Change foo.bar.baz to foo/bar/baz */ Xextern int errcnt; /* number of files unreadable */ Xextern int Optiong; /* Let it rip no wait for sector ACK's */ SHAR_EOF echo "End of part 1" echo "File COMMON.H is continued in part 2" echo "2" > s2_seq_.tmp exit 0