Annotation of researchv10no/cmd/spitbol/cint/rbsb.sh, revision 1.1

1.1     ! root        1: #      This is a shell archive.
        !             2: #      Remove everything above and including the cut line.
        !             3: #      Then run the rest of the file through sh.
        !             4: -----cut here-----cut here-----cut here-----cut here-----
        !             5: #!/bin/sh
        !             6: # shar:        Shell Archiver
        !             7: #      Run the following text with /bin/sh to create:
        !             8: #      rb.1
        !             9: #      rb.c
        !            10: #      rbsb.c
        !            11: #      sb.1
        !            12: #      sb.c
        !            13: #      undos.1
        !            14: #      undos.c
        !            15: # This archive created: Fri Jan 10 12:33:41 1986
        !            16: cat << \SHAR_EOF > rb.1
        !            17: '\" Revision Level 
        !            18: '\" Last Delta     12-16-85
        !            19: .TH RB 1 OMEN
        !            20: .SH NAME
        !            21: rb \- YMODEM batch file receive
        !            22: .SH SYNOPSIS
        !            23: .B rb
        !            24: [
        !            25: .B \-bquv
        !            26: ]
        !            27: .PP
        !            28: .B rb
        !            29: [
        !            30: .B \-bcquv
        !            31: ]
        !            32: .B file
        !            33: .PP
        !            34: .B [-][v]rbCOMMAND
        !            35: .SH DESCRIPTION
        !            36: .B Rb
        !            37: receives 0 or more files in batch mode.
        !            38: Iff
        !            39: .B file
        !            40: is speficied,
        !            41: a single file is received in XMODEM single file mode.
        !            42: 
        !            43: Normally, the file contents are converted to
        !            44: .SM Unix
        !            45: conventions by stripping carriage returns and all characters
        !            46: beginning with Control Z (CP/M end of file).
        !            47: If the raw pathname ends in
        !            48: ".A",
        !            49: ".ARC",
        !            50: ".CCC",
        !            51: ".CL",
        !            52: ".CMD",
        !            53: ".COM",
        !            54: ".CRL",
        !            55: ".DAT",
        !            56: ".DIR",
        !            57: ".EXE",
        !            58: ".O",
        !            59: ".OBJ",
        !            60: ".OVL",
        !            61: ".PAG",
        !            62: ".REL",
        !            63: ".SAV",
        !            64: ".SUB",
        !            65: ".SWP",
        !            66: ".SYS",
        !            67: ".TAR",
        !            68: ".UTL",
        !            69: ".a",
        !            70: ".o",
        !            71: ".tar",
        !            72: or if the first sector contains
        !            73: data that suggest a binary file
        !            74: (parity bits or characters in the range 000 to 006 before the first ^Z),
        !            75: or if the file mode is transmitted and the 0100000 bit is set,
        !            76: that file will be received in binary mode anyway.
        !            77: 
        !            78: Otherwise,
        !            79: if the raw pathname ends in .MSG, or .TXT, any existing file will
        !            80: be appended to rather than replaced.
        !            81: 
        !            82: Normally, each file name is converted to lower case
        !            83: unless it contains one or more lower case letters.
        !            84: 
        !            85: Rb works with either standard 128 byte sectors or
        !            86: 1024 byte sectors
        !            87: (YAM
        !            88: .B k
        !            89: option).
        !            90: The user should determine experimentally
        !            91: the conditions under which use of 1k blocks
        !            92: actually improves throughput without causing
        !            93: problems.
        !            94: 
        !            95: If extended file information (file length, etc.)
        !            96: is received,
        !            97: the file length controls the number of bytes written to
        !            98: the output dataset,
        !            99: and the modify time and file mode
        !           100: (iff non zero)
        !           101: are set accordingly.
        !           102: 
        !           103: If no extended file information is received,
        !           104: slashes in the pathname are changed to underscore,
        !           105: and any trailing period in the pathname is eliminated.
        !           106: 
        !           107: If rb is invoked with stdout and stderr to different datasets,
        !           108: Verbose is set to 2, causing frame by frame progress reports
        !           109: to stderr.
        !           110: This may be disabled with the
        !           111: .B q
        !           112: option.
        !           113: 
        !           114: If the SHELL environment variable includes
        !           115: .I "rsh"
        !           116: or
        !           117: .I "rksh"
        !           118: (restricted shell),
        !           119: rb will not accept pathnames containing referenced to absolute paths
        !           120: or to a parent directory, will not receive to an existing file, and
        !           121: removes any files received in error.
        !           122: 
        !           123: .PP
        !           124: The meanings of the available options are:
        !           125: .PP
        !           126: .PD 0
        !           127: .TP
        !           128: .B b
        !           129: transfer all files in binary
        !           130: (tell it like it is)
        !           131: mode.
        !           132: This option disables any append mode special processing.
        !           133: .TP
        !           134: .B c
        !           135: Request 16 bit cyclic redundancy check
        !           136: (8 bit checksum default).
        !           137: .TP
        !           138: .B q
        !           139: Quiet suppresses verbosity.
        !           140: .TP
        !           141: .B v
        !           142: .IR Verbose
        !           143: causes a list of file
        !           144: names to be appended to
        !           145: /tmp/rblog .
        !           146: More v's generate more output.
        !           147: .TP
        !           148: .B u
        !           149: Retain upper case letters in file names unconditionally.
        !           150: .PD
        !           151: .SH EXAMPLES
        !           152: (
        !           153: .SM Unix
        !           154: command)
        !           155: .RS
        !           156: $rb
        !           157: .br
        !           158: rb: ready C
        !           159: .br
        !           160: .RE
        !           161: (Pro-YAM command)
        !           162: .RS
        !           163: <F1>
        !           164: .br
        !           165: >>>c: sbt *.h *.c
        !           166: .br
        !           167: .RE
        !           168: .SH SEE ALSO
        !           169: YMODEM.DOC,
        !           170: IMP(CP/M),
        !           171: ncu(1),
        !           172: Professional-YAM manual,
        !           173: sb(omen),
        !           174: usq(omen),
        !           175: undos(omen)
        !           176: 
        !           177: Compile time options for various operating systems are described in the
        !           178: program source file.
        !           179: .SH NOTES
        !           180: If rb is invoked as
        !           181: .B rbCOMMAND
        !           182: (with an optional leading \- as generated by login(1)),
        !           183: rb will pipe each received file to ``COMMAND filename''
        !           184: (filename is the name of the transmitted file)
        !           185: with the file contents as standard input.
        !           186: A typical usage for this form is rbrmail which calls rmail
        !           187: to post mail.
        !           188: On some
        !           189: .SM Unix
        !           190: systems, the login directory must contain
        !           191: COMMAND as login sets SHELL=rsh which disallows absolute
        !           192: pathnames.
        !           193: If invoked with a leading ``v'' rb will report progress to LOGFILE.
        !           194: The following entry works for
        !           195: .SM Unix
        !           196: 3.0.
        !           197:        rbrmail::5:1::/bin:/usr/local/rbrmail
        !           198: .PP
        !           199: The following (in a shell script)
        !           200: may be used to fetch file(s) from a remote computer connected to /dev/tty7
        !           201: once sb has been started on the remote.
        !           202:        rb -v >/dev/tty7 </dev/tty7
        !           203: .SH BUGS
        !           204: Pathnames are restricted to 127 characters.
        !           205: 
        !           206: In XMODEM single file mode, the pathname given on the command line
        !           207: is still processed as described above.
        !           208: 
        !           209: The CR/LF to NL translation merely deletes CR\'s;
        !           210: undos(omen) performs a more intelligent translation.
        !           211: .SH "VMS VERSION"
        !           212: Some of the #includes with file names enclosed with angle brackets <>
        !           213: may need to have the angle brackets removed, or vice versa.
        !           214: 
        !           215: The VMS version does not set binary mode according to the incoming
        !           216: file type.
        !           217: Non binary file processing consists of stripping all characters beginning
        !           218: with CPMEOF (^Z).
        !           219: 
        !           220: The VMS version does not set the file time.
        !           221: 
        !           222: VMS occaisonally loses incoming characters, resulting in retries
        !           223: and degradation of throughput.
        !           224: 
        !           225: There may be unknown interactions between the VMS C standard i/o
        !           226: package and RMS.
        !           227: 
        !           228: The VMS version does not support invocation as
        !           229: .B rbCOMMAND .
        !           230: SHAR_EOF
        !           231: cat << \SHAR_EOF > rb.c
        !           232: #define VERSION "2.17 12-07-85"
        !           233: #define PUBDIR "/usr/spool/uucppublic"
        !           234: 
        !           235: /*% cc -DUSG -DNFGVMIN -O -K % -o rb
        !           236:  *
        !           237:  * rb.c By Chuck Forsberg
        !           238:  *
        !           239:  *  USG UNIX (3.0) ioctl conventions courtesy  Jeff Martin
        !           240:  *     cc -O -DV7  rb.c -o rb          Unix V7, BSD 2.8 - 4.2
        !           241:  *     cc -O -DUSG rb.c -o rb          USG (3.0) Unix
        !           242:  *     cc -o rb.c                      Regulus
        !           243:  *             (Don't try this on Unix, you'll clobber the source!)
        !           244:  *  Unix is a trademark of Western Electric Company
        !           245:  *
        !           246:  *  Regulus conventions 1-10-83 CAF
        !           247:  *
        !           248:  *  Some systems (Venix, Coherent, Regulus) do not support tty raw mode
        !           249:  *  read(2) the same way as Unix. ONEREAD must be defined to force one
        !           250:  *  character reads for these systems. Added 7-01-84 CAF
        !           251:  *
        !           252:  *  Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF 
        !           253:  *
        !           254:  *  NFGVMIN Added 1-13-85 CAF for PC-AT Xenix systems where c_cc[VMIN]
        !           255:  *  doesn't seem to work (even though it compiles without error!).
        !           256:  *
        !           257:  * A program for Unix which can receive
        !           258:  *  files from computers running YAM or MODEM.
        !           259:  *  rb uses Unix System III buffered input to reduce CPU time.
        !           260:  *  If no filename is given, YAM batch mode is assumed.
        !           261:  *
        !           262:  * Iff the program is invoked by rbCOMMAND, output is piped to 
        !           263:  * "COMMAND filename"
        !           264:  *
        !           265:  *  Supports the CRC option or regular checksum.
        !           266:  *  Received pathnames containing no lowercase letters will be changed to lower
        !           267:  *  case unless -u option is given.
        !           268:  *
        !           269:  *  Unless the -b (binary) option is given, \r is discarded and
        !           270:  *  ^Z (which is also discarded) acts as end of file.
        !           271:  *
        !           272:  *  Any slashes in the pathname are changed to underscore.
        !           273:  *  If the raw pathname ends in .MSG or .TXT, any existing file will
        !           274:  *  be appended to rather than replaced. Trailing periods are eliminated.
        !           275:  *
        !           276:  *  If the raw pathname ends in any of the extensions in Extensions,
        !           277:  *   or .?Q* (squeezed file), or if the first sector contains binary-like
        !           278:  *   data (parity bits or characters in the range 0 to 6 before ^Z is seen),
        !           279:  *   or if the transmitted file mode has the 0100000 but set,
        !           280:  *   that file will be received in binary mode anyway.
        !           281:  *
        !           282:  *
        !           283:  * A log of activities is appended to LOGFILE with the -v option
        !           284:  * If stdout and stderr refer to different devices, progress is displayed to
        !           285:  * stderr.
        !           286:  *
        !           287:  * rb is derived from yam2.c and sb.c
        !           288:  */
        !           289: #define LOGFILE "/tmp/rblog"
        !           290: 
        !           291: #include <stdio.h>
        !           292: #include <signal.h>
        !           293: #include <setjmp.h>
        !           294: #include <ctype.h>
        !           295: FILE *popen();
        !           296: 
        !           297: #define OK 0
        !           298: #define FALSE 0
        !           299: #define TRUE 1
        !           300: #define ERROR (-1)
        !           301: 
        !           302: #define HOWMANY 133
        !           303: #include "rbsb.c"      /* most of the system dependent stuff here */
        !           304: 
        !           305: char *substr();
        !           306: FILE *fout;
        !           307: 
        !           308: char *Extensions[] = {
        !           309: ".A",
        !           310: ".ARC",
        !           311: ".CCC",
        !           312: ".CL",
        !           313: ".CMD",
        !           314: ".COM",
        !           315: ".CRL",
        !           316: ".DAT",
        !           317: ".DIR",
        !           318: ".EXE",
        !           319: ".O",
        !           320: ".OBJ",
        !           321: ".OVL",
        !           322: ".PAG",
        !           323: ".REL",
        !           324: ".SAV",
        !           325: ".SUB",
        !           326: ".SWP",
        !           327: ".SYS",
        !           328: ".TAR",
        !           329: ".UTL",
        !           330: ".a",
        !           331: ".o",
        !           332: ".tar",
        !           333: ""
        !           334: };
        !           335: 
        !           336: /* Ward Christensen / CP/M parameters - Don't change these! */
        !           337: #define ENQ 005
        !           338: #define CAN ('X'&037)
        !           339: #define XOFF ('s'&037)
        !           340: #define XON ('q'&037)
        !           341: #define SOH 1
        !           342: #define STX 2
        !           343: #define EOT 4
        !           344: #define ACK 6
        !           345: #define NAK 025
        !           346: #define CPMEOF 032
        !           347: #define WANTCRC 0103   /* send C not NAK to get crc not checksum */
        !           348: #define TIMEOUT (-2)
        !           349: #define ERRORMAX 5
        !           350: #define RETRYMAX 5
        !           351: #define WCEOT (-10)
        !           352: #define SECSIZ 128     /* cp/m's Magic Number record size */
        !           353: #define PATHLEN 257    /* ready for 4.2 bsd ? */
        !           354: #define KSIZE 1024     /* record size with k option */
        !           355: #define UNIXFILE 0x8000        /* happens to the the S_IFREG file mask bit for stat */
        !           356: 
        !           357: int Lastrx;
        !           358: int Crcflg;
        !           359: int Firstsec;
        !           360: int Eofseen;           /* indicates cpm eof (^Z) has been received */
        !           361: int totblocks;         /* total number of blocks received */
        !           362: int errors;
        !           363: int Restricted=0;      /* restricted; no /.. or ../ in filenames */
        !           364: 
        !           365: #define DEFBYTL 2000000000L    /* default rx file size */
        !           366: long Bytesleft;                /* number of bytes of incoming file left */
        !           367: long Modtime;          /* Unix style mod time for incoming file */
        !           368: short Filemode;                /* Unix style mode for incoming file */
        !           369: char Pathname[PATHLEN];
        !           370: char *Progname;                /* the name by which we were called */
        !           371: 
        !           372: int Batch=0;
        !           373: int Wcsmask=0377;
        !           374: int Topipe=0;
        !           375: int MakeLCPathname=TRUE;       /* make received pathname lower case */
        !           376: int Verbose=0;
        !           377: int Quiet=0;           /* overrides logic that would otherwise set verbose */
        !           378: int Rxbinary=FALSE;    /* receive all files in bin mode */
        !           379: int Thisbinary;                /* current file is to be received in bin mode */
        !           380: int Blklen;            /* record length of received packets */
        !           381: char secbuf[KSIZE];
        !           382: char linbuf[KSIZE];
        !           383: int Lleft=0;           /* number of characters in linbuf */
        !           384: 
        !           385: jmp_buf tohere;                /* For the interrupt on RX timeout */
        !           386: 
        !           387: unsigned short updcrc();
        !           388: 
        !           389: alrm()
        !           390: {
        !           391:        longjmp(tohere, -1);
        !           392: }
        !           393: 
        !           394: /* called by signal interrupt or terminate to clean things up */
        !           395: bibi(n)
        !           396: {
        !           397:        canit(); mode(0);
        !           398:        fprintf(stderr, "sb: caught signal %d; exiting", n);
        !           399:        exit(128+n);
        !           400: }
        !           401: 
        !           402: main(argc, argv)
        !           403: char *argv[];
        !           404: {
        !           405:        register char *cp;
        !           406:        register npats;
        !           407:        char *virgin, **patts;
        !           408:        char *getenv();
        !           409:        int exitcode;
        !           410: 
        !           411:        setbuf(stderr, NULL);
        !           412:        if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rsh")))
        !           413:                Restricted=TRUE;
        !           414: 
        !           415:        chkinvok(virgin=argv[0]);       /* if called as [-]rbCOMMAND set flag */
        !           416:        npats = 0;
        !           417:        while (--argc) {
        !           418:                cp = *++argv;
        !           419:                if (*cp == '-') {
        !           420:                        while( *++cp) {
        !           421:                                switch(*cp) {
        !           422:                                case '1':
        !           423:                                        iofd = 1; break;
        !           424:                                case '7':
        !           425:                                        Wcsmask = 0177;
        !           426:                                case 'b':
        !           427:                                        Rxbinary=TRUE; break;
        !           428:                                case 'k':
        !           429:                                case 'c':
        !           430:                                        Crcflg=TRUE; break;
        !           431:                                case 'q':
        !           432:                                        Quiet=TRUE; Verbose=0; break;
        !           433:                                case 'u':
        !           434:                                        MakeLCPathname=FALSE; break;
        !           435:                                case 'v':
        !           436:                                        ++Verbose; break;
        !           437:                                default:
        !           438:                                        usage();
        !           439:                                }
        !           440:                        }
        !           441:                }
        !           442:                else if ( !npats && argc>0) {
        !           443:                        if (argv[0][0]) {
        !           444:                                npats=argc;
        !           445:                                patts=argv;
        !           446:                        }
        !           447:                }
        !           448:        }
        !           449:        if (npats > 1)
        !           450:                usage();
        !           451:        if (Verbose) {
        !           452:                if (freopen(LOGFILE, "a", stderr)==NULL) {
        !           453:                        printf("Can't open log file %s\n",LOGFILE);
        !           454:                        exit(0200);
        !           455:                }
        !           456:                setbuf(stderr, NULL);
        !           457:                fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname);
        !           458:        }
        !           459:        if (fromcu() && !Quiet) {
        !           460:                if (Verbose == 0)
        !           461:                        Verbose = 2;
        !           462:        }
        !           463:        mode(1);
        !           464:        if (signal(SIGINT, bibi) == SIG_IGN) {
        !           465:                signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
        !           466:        }
        !           467:        else {
        !           468:                signal(SIGINT, bibi); signal(SIGKILL, bibi);
        !           469:        }
        !           470:        if (wcreceive(npats, patts)==ERROR) {
        !           471:                exitcode=0200;
        !           472:                canit();
        !           473:        }
        !           474:        mode(0);
        !           475:        if (exitcode != 0)      /* bellow again with all thy might. */
        !           476:                canit();
        !           477: #ifdef REGULUS
        !           478:        else
        !           479:                printf("\6\6\6\6\6\n"); /* Regulus doesn't wait ... */
        !           480: #endif
        !           481:        exit(exitcode);
        !           482: }
        !           483: 
        !           484: 
        !           485: usage()
        !           486: {
        !           487:        fprintf(stderr,"%s %s by Chuck Forsberg\n", Progname, VERSION);
        !           488:        fprintf(stderr,"Usage:  rb [-17buv]\n\tor rb [-1bcuv] file\n");
        !           489:        exit(1);
        !           490: }
        !           491: 
        !           492: wcreceive(argc, argp)
        !           493: char **argp;
        !           494: {
        !           495:        if (Batch || argc==0) {
        !           496:                Crcflg=(Wcsmask==0377);
        !           497:                fprintf(stderr, "rb: ready ");
        !           498:                for (;;) {
        !           499:                        totblocks=0;
        !           500:                        if (wcrxpn(secbuf)== ERROR)
        !           501:                                goto fubar;
        !           502:                        if (secbuf[0]==0)
        !           503:                                return OK;
        !           504:                        if (procheader(secbuf) == ERROR)
        !           505:                                goto fubar;
        !           506:                        if (wcrx()==ERROR)
        !           507:                                goto fubar;
        !           508:                }
        !           509:        } else {
        !           510:                totblocks=0; Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
        !           511: 
        !           512:                strcpy(Pathname, *argp);
        !           513:                checkpath(Pathname);
        !           514:                fprintf(stderr, "\nrb: ready to receive %s ", Pathname);
        !           515:                if ((fout=fopen(Pathname, "w")) == NULL)
        !           516:                        return ERROR;
        !           517:                if (wcrx()==ERROR)
        !           518:                        goto fubar;
        !           519:        }
        !           520:        return OK;
        !           521: fubar:
        !           522:        canit();
        !           523:        if (Topipe && fout) {
        !           524:                pclose(fout);  return ERROR;
        !           525:        }
        !           526:        if (fout)
        !           527:                fclose(fout);
        !           528:        if (Restricted) {
        !           529:                unlink(Pathname);
        !           530:                fprintf(stderr, "\r\nrb: %s removed.\r\n", Pathname);
        !           531:        }
        !           532:        return ERROR;
        !           533: }
        !           534: 
        !           535: 
        !           536: /*
        !           537:  * Fetch a pathname from the other end as a C ctyle ASCIZ string.
        !           538:  * Length is indeterminate as long as less than Blklen
        !           539:  * a null string represents no more files
        !           540:  */
        !           541: wcrxpn(rpn)
        !           542: char *rpn;     /* receive a pathname */
        !           543: {
        !           544:        register c;
        !           545: 
        !           546: #ifdef NFGVMIN
        !           547:        readline(1);
        !           548: #else
        !           549:        purgeline();
        !           550: #endif
        !           551: 
        !           552: et_tu:
        !           553:        Firstsec=TRUE;
        !           554:        sendline(Crcflg?WANTCRC:NAK);
        !           555:        while ((c = wcgetsec(rpn, 100)) != 0) {
        !           556:                log( "Pathname fetch returned %d\n", c);
        !           557:                if (c == WCEOT) {
        !           558:                        sendline(ACK); readline(1); goto et_tu;
        !           559:                }
        !           560:                return ERROR;
        !           561:        }
        !           562:        sendline(ACK);
        !           563:        return OK;
        !           564: }
        !           565: 
        !           566: /*
        !           567:  * Adapted from CMODEM13.C, written by
        !           568:  * Jack M. Wierda and Roderick W. Hart
        !           569:  */
        !           570: 
        !           571: wcrx()
        !           572: {
        !           573:        register int sectnum, sectcurr;
        !           574:        register char sendchar;
        !           575:        register char *p;
        !           576:        int cblklen;                    /* bytes to dump this block */
        !           577:        time_t timep[2];
        !           578: 
        !           579:        Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
        !           580:        sendchar=Crcflg?WANTCRC:NAK;
        !           581: 
        !           582:        for (;;) {
        !           583:                sendline(sendchar);     /* send it now, we're ready! */
        !           584:                sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
        !           585:                report(sectcurr);
        !           586:                if (sectcurr==(sectnum+1 &Wcsmask)) {
        !           587: 
        !           588:                        if (sectnum==0 && !Thisbinary)
        !           589:                                for (p=secbuf,sectcurr=Blklen;
        !           590:                                  *p != 032 && --sectcurr>=0; ++p)
        !           591:                                        if (*p < 07 || (*p & 0200)) {
        !           592:                                                Thisbinary++;
        !           593:                                                if (Verbose)
        !           594:                                                        fprintf(stderr, "Changed to BIN\n");
        !           595:                                                break;
        !           596:                                        }
        !           597:                        sectnum++;
        !           598:                        cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
        !           599:                        if (putsec(secbuf, cblklen)==ERROR)
        !           600:                                return ERROR;
        !           601:                        if ((Bytesleft-=cblklen) < 0)
        !           602:                                Bytesleft = 0;
        !           603:                        sendchar=ACK;
        !           604:                }
        !           605:                else if (sectcurr==(sectnum&Wcsmask)) {
        !           606:                        log( "Received dup Sector\n");
        !           607:                        sendchar=ACK;
        !           608:                }
        !           609:                else if (sectcurr==WCEOT) {
        !           610:                        if (Topipe) {
        !           611:                                if (pclose(fout)!=ERROR) {
        !           612:                                        sendline(ACK);
        !           613:                                        return OK;
        !           614:                                }
        !           615:                                canit(); return ERROR;
        !           616:                        }
        !           617:                        if (fclose(fout)==ERROR) {
        !           618:                                canit();
        !           619:                                fprintf(stderr, "file close ERROR\n");
        !           620:                                return ERROR;
        !           621:                        }
        !           622:                        if (Modtime) {
        !           623:                                timep[0] = time(NULL);
        !           624:                                timep[1] = Modtime;
        !           625:                                utime(Pathname, timep);
        !           626:                        }
        !           627:                        if (Filemode)
        !           628:                                chmod(Pathname, (07777 & Filemode));
        !           629:                        sendline(ACK);
        !           630:                        return OK;
        !           631:                }
        !           632:                else if (sectcurr==ERROR)
        !           633:                        return ERROR;
        !           634:                else {
        !           635:                        log( "Sync Error\n");
        !           636:                        return ERROR;
        !           637:                }
        !           638:        }
        !           639: }
        !           640: 
        !           641: /*
        !           642:  * wcgetsec fetches a Ward Christensen type sector.
        !           643:  * Returns sector number encountered or ERROR if valid sector not received,
        !           644:  * or CAN CAN received
        !           645:  * or WCEOT if eot sector
        !           646:  * time is timeout for first char, set to 4 seconds thereafter
        !           647:  ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
        !           648:  *    (Caller must do that when he is good and ready to get next sector)
        !           649:  */
        !           650: 
        !           651: wcgetsec(rxbuf, maxtime)
        !           652: char *rxbuf;
        !           653: int maxtime;
        !           654: {
        !           655:        register checksum, wcj, firstch;
        !           656:        register unsigned short oldcrc;
        !           657:        register char *p;
        !           658:        int sectcurr;
        !           659: 
        !           660:        for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
        !           661: 
        !           662:                if ((firstch=readline(maxtime))==STX) {
        !           663:                        Blklen=KSIZE; goto get2;
        !           664:                }
        !           665:                if (firstch==SOH) {
        !           666:                        Blklen=SECSIZ;
        !           667: get2:
        !           668:                        sectcurr=readline(1);
        !           669:                        if ((sectcurr+(oldcrc=readline(1)))==Wcsmask) {
        !           670:                                oldcrc=checksum=0;
        !           671:                                for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
        !           672:                                        if ((firstch=readline(1)) < 0)
        !           673:                                                goto bilge;
        !           674:                                        oldcrc=updcrc(firstch, oldcrc);
        !           675:                                        checksum += (*p++ = firstch);
        !           676:                                }
        !           677:                                if ((firstch=readline(1)) < 0)
        !           678:                                        goto bilge;
        !           679:                                if (Crcflg) {
        !           680:                                        oldcrc=updcrc(firstch, oldcrc);
        !           681:                                        if ((firstch=readline(1)) < 0)
        !           682:                                                goto bilge;
        !           683:                                        oldcrc=updcrc(firstch, oldcrc);
        !           684:                                        if (oldcrc)
        !           685:                                                log("CRC=0%o\n", oldcrc);
        !           686:                                        else {
        !           687:                                                Firstsec=FALSE;
        !           688:                                                return sectcurr;
        !           689:                                        }
        !           690:                                }
        !           691:                                else if (((checksum-firstch)&Wcsmask)==0) {
        !           692:                                        Firstsec=FALSE;
        !           693:                                        return sectcurr;
        !           694:                                }
        !           695:                                else
        !           696:                                        log( "Checksum Error\n");
        !           697:                        }
        !           698:                        else
        !           699:                                log("Sector number garbled 0%o 0%o\n",
        !           700:                                 sectcurr, oldcrc);
        !           701:                }
        !           702:                /* make sure eot really is eot and not just mixmash */
        !           703: #ifdef NFGVMIN
        !           704:                else if (firstch==EOT && readline(1)==TIMEOUT)
        !           705:                        return WCEOT;
        !           706: #else
        !           707:                else if (firstch==EOT && Lleft==0)
        !           708:                        return WCEOT;
        !           709: #endif
        !           710:                else if (firstch==CAN) {
        !           711:                        if (Lastrx==CAN) {
        !           712:                                log( "Sender CANcelled\n");
        !           713:                                return ERROR;
        !           714:                        } else {
        !           715:                                Lastrx=CAN;
        !           716:                                continue;
        !           717:                        }
        !           718:                }
        !           719:                else if (firstch==TIMEOUT) {
        !           720:                        if (Firstsec)
        !           721:                                goto humbug;
        !           722: bilge:
        !           723:                        log( "Timeout\n");
        !           724:                }
        !           725:                else
        !           726:                        log( "Got 0%o sector header\n", firstch);
        !           727: 
        !           728: humbug:
        !           729:                Lastrx=0;
        !           730:                while(readline(1)!=TIMEOUT)
        !           731:                        ;
        !           732:                if (Firstsec)
        !           733:                        sendline(Crcflg?WANTCRC:NAK);
        !           734:                else {
        !           735:                        maxtime=40; sendline(NAK);
        !           736:                }
        !           737:        }
        !           738:        /* try to stop the bubble machine. */
        !           739:        canit();
        !           740:        return ERROR;
        !           741: }
        !           742: 
        !           743: /*
        !           744:  * This version of readline is reasoably well suited for
        !           745:  * reading many characters.
        !           746:  *  (except, currently, for the Regulus version!)
        !           747:  *
        !           748:  * timeout is in tenths of seconds
        !           749:  */
        !           750: readline(timeout)
        !           751: int timeout;
        !           752: {
        !           753:        register n;
        !           754:        static char *cdq;       /* pointer for removing chars from linbuf */
        !           755: 
        !           756:        if (--Lleft >= 0) {
        !           757:                if (Verbose > 8) {
        !           758:                        fprintf(stderr, "%02x ", *cdq&0377);
        !           759:                }
        !           760:                return (*cdq++ & Wcsmask);
        !           761:        }
        !           762:        n = timeout/10;
        !           763:        if (n < 2)
        !           764:                n = 3;
        !           765:        if (Verbose > 3)
        !           766:                fprintf(stderr, "Calling read: n=%d ", n);
        !           767:        if (setjmp(tohere)) {
        !           768: #ifdef TIOCFLUSH
        !           769: /*             ioctl(iofd, TIOCFLUSH, 0); */
        !           770: #endif
        !           771:                Lleft = 0;
        !           772:                if (Verbose>1)
        !           773:                        fprintf(stderr, "Readline:TIMEOUT\n");
        !           774:                return TIMEOUT;
        !           775:        }
        !           776:        signal(SIGALRM, alrm); alarm(n);
        !           777: #ifdef ONEREAD
        !           778:        /* Sorry, Regulus and some others don't work right in raw mode! */
        !           779:        Lleft=read(iofd, cdq=linbuf, 1);
        !           780: #else
        !           781:        Lleft=read(iofd, cdq=linbuf, KSIZE);
        !           782: #endif
        !           783:        alarm(0);
        !           784:        if (Verbose > 3) {
        !           785:                fprintf(stderr, "Read returned %d bytes\n", Lleft);
        !           786:        }
        !           787:        if (Lleft < 1)
        !           788:                return TIMEOUT;
        !           789:        --Lleft;
        !           790:        if (Verbose > 8) {
        !           791:                fprintf(stderr, "%02x ", *cdq&0377);
        !           792:        }
        !           793:        return (*cdq++ & Wcsmask);
        !           794: }
        !           795: 
        !           796: 
        !           797: 
        !           798: 
        !           799: purgeline()
        !           800: {
        !           801:        Lleft = 0;
        !           802: #ifdef USG
        !           803:        ioctl(iofd, TCFLSH, 0);
        !           804: #else
        !           805:        lseek(iofd, 0L, 2);
        !           806: #endif
        !           807: }
        !           808: 
        !           809: /* update CRC */
        !           810: unsigned short
        !           811: updcrc(c, crc)
        !           812: register c;
        !           813: register unsigned crc;
        !           814: {
        !           815:        register count;
        !           816: 
        !           817:        for (count=8; --count>=0;) {
        !           818:                if (crc & 0x8000) {
        !           819:                        crc <<= 1;
        !           820:                        crc += (((c<<=1) & 0400)  !=  0);
        !           821:                        crc ^= 0x1021;
        !           822:                }
        !           823:                else {
        !           824:                        crc <<= 1;
        !           825:                        crc += (((c<<=1) & 0400)  !=  0);
        !           826:                }
        !           827:        }
        !           828:        return crc;     
        !           829: }
        !           830: 
        !           831: /*
        !           832:  * process incoming header
        !           833:  */
        !           834: procheader(name)
        !           835: char *name;
        !           836: {
        !           837:        register char *openmode, *p, **pp;
        !           838: 
        !           839:        /* set default parameters */
        !           840:        openmode = "w"; Thisbinary=Rxbinary;
        !           841:        Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
        !           842: 
        !           843:        p = name + 1 + strlen(name);
        !           844:        if (*p) {       /* file coming from Unix or DOS system */
        !           845:                sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
        !           846:                if (Filemode & UNIXFILE)
        !           847:                        ++Thisbinary;
        !           848:                if (Verbose) {
        !           849:                        fprintf(stderr,  "Incoming: %s %ld %lo %o\n",
        !           850:                          name, Bytesleft, Modtime, Filemode);
        !           851:                }
        !           852:        }
        !           853:        else {          /* File coming from CP/M system */
        !           854:                for (p=name; *p; ++p)           /* change / to _ */
        !           855:                        if ( *p == '/')
        !           856:                                *p = '_';
        !           857: 
        !           858:                if ( *--p == '.')               /* zap trailing period */
        !           859:                        *p = 0;
        !           860:        }
        !           861: 
        !           862:        /* scan for extensions that signify a binary file */
        !           863:        if (p=substr(name, "."))
        !           864:                for (pp=Extensions; **pp; ++pp)
        !           865:                        if (strcmp(p, *pp)==0) {
        !           866:                                Thisbinary=TRUE; break;
        !           867:                        }
        !           868: 
        !           869:        /* scan for files which should be appended */
        !           870:        if ( !Thisbinary
        !           871:          && (substr(name, ".TXT")
        !           872:          || substr(name, ".txt")
        !           873:          || substr(name, ".MSG")))
        !           874:                openmode = "a";
        !           875:        if (MakeLCPathname && !IsAnyLower(name))
        !           876:                uncaps(name);
        !           877:        if (Topipe) {
        !           878:                sprintf(Pathname, "%s %s", Progname+2, name);
        !           879:                if (Verbose)
        !           880:                        fprintf(stderr,  "Topipe: %s %s\n",
        !           881:                          Pathname, Thisbinary?"BIN":"ASCII");
        !           882:                if ((fout=popen(Pathname, "w")) == NULL)
        !           883:                        return ERROR;
        !           884:        } else {
        !           885:                strcpy(Pathname, name);
        !           886:                if (Verbose) {
        !           887:                        fprintf(stderr,  "Receiving %s %s %s\n",
        !           888:                          name, Thisbinary?"BIN":"ASCII", openmode);
        !           889:                }
        !           890:                checkpath(name);
        !           891:                if ((fout=fopen(name, openmode)) == NULL)
        !           892:                        return ERROR;
        !           893:        }
        !           894:        return OK;
        !           895: }
        !           896: 
        !           897: /* make string s lower case */
        !           898: uncaps(s)
        !           899: register char *s;
        !           900: {
        !           901:        for ( ; *s; ++s)
        !           902:                if (isupper(*s))
        !           903:                        *s = tolower(*s);
        !           904: }
        !           905: 
        !           906: 
        !           907: /*
        !           908:  * IsAnyLower returns TRUE if string s has lower case letters.
        !           909:  */
        !           910: IsAnyLower(s)
        !           911: register char *s;
        !           912: {
        !           913:        for ( ; *s; ++s)
        !           914:                if (islower(*s))
        !           915:                        return TRUE;
        !           916:        return FALSE;
        !           917: }
        !           918: /*
        !           919:  * putsec writes the n characters of buf to receive file fout.
        !           920:  *  If not in binary mode, carriage returns, and all characters
        !           921:  *  starting with CPMEOF are discarded.
        !           922:  */
        !           923: putsec(buf, n)
        !           924: char *buf;
        !           925: register n;
        !           926: {
        !           927:        register char *p;
        !           928: 
        !           929:        ++totblocks;
        !           930:        if (Thisbinary)
        !           931:        {
        !           932:                for (p=buf; --n>=0; )
        !           933:                        putc( *p++, fout);
        !           934:        }
        !           935:        else {
        !           936:                if (Eofseen)
        !           937:                        return OK;
        !           938:                for (p=buf; --n>=0; ++p ) {
        !           939:                        if ( *p == '\r')
        !           940:                                continue;
        !           941:                        if (*p == CPMEOF) {
        !           942:                                Eofseen=TRUE; return OK;
        !           943:                        }
        !           944:                        putc(*p ,fout);
        !           945:                }
        !           946:        }
        !           947:        return OK;
        !           948: }
        !           949: sendline(c)
        !           950: {
        !           951:        char d;
        !           952: 
        !           953:        d = c;
        !           954:        if (Verbose>2)
        !           955:                fprintf(stderr, "Sendline: %x\n", c);
        !           956:        write(1, &d, 1);
        !           957:        Lleft=0;        /* Do read next time ... */
        !           958: }
        !           959: 
        !           960: 
        !           961: /*
        !           962:  * substr(string, token) searches for token in string s
        !           963:  * returns pointer to token within string if found, NULL otherwise
        !           964:  */
        !           965: char *
        !           966: substr(s, t)
        !           967: register char *s,*t;
        !           968: {
        !           969:        register char *ss,*tt;
        !           970:        /* search for first char of token */
        !           971:        for (ss=s; *s; s++)
        !           972:                if (*s == *t)
        !           973:                        /* compare token with substring */
        !           974:                        for (ss=s,tt=t; ;) {
        !           975:                                if (*tt == 0)
        !           976:                                        return s;
        !           977:                                if (*ss++ != *tt++)
        !           978:                                        break;
        !           979:                        }
        !           980:        return NULL;
        !           981: }
        !           982: 
        !           983: /*VARARGS1*/
        !           984: log(s,p,u)
        !           985: char *s, *p, *u;
        !           986: {
        !           987:        if (!Verbose)
        !           988:                return;
        !           989:        fprintf(stderr, "error %d: ", errors);
        !           990:        fprintf(stderr, s, p, u);
        !           991: }
        !           992: 
        !           993: /* send 10 CAN's to try to get the other end to shut up */
        !           994: canit()
        !           995: {
        !           996:        register n;
        !           997:        for (n=10; --n>=0; )
        !           998:                sendline(CAN);
        !           999: }
        !          1000: 
        !          1001: #ifdef REGULUS
        !          1002: /*
        !          1003:  * copies count bytes from s to d
        !          1004:  * (No structure assignment in Regulus C compiler)
        !          1005:  */
        !          1006: 
        !          1007: movmem(s, d, count)
        !          1008: register char *s, *d;
        !          1009: register count;
        !          1010: {
        !          1011:        while (--count >= 0)
        !          1012:                *d++ = *s++;
        !          1013: }
        !          1014: #endif
        !          1015: 
        !          1016: /*
        !          1017:  * return 1 iff stdout and stderr are different devices
        !          1018:  *  indicating this program operating with a modem on a
        !          1019:  *  different line
        !          1020:  */
        !          1021: fromcu()
        !          1022: {
        !          1023:        struct stat a, b;
        !          1024:        fstat(1, &a); fstat(2, &b);
        !          1025:        return (a.st_rdev != b.st_rdev);
        !          1026: }
        !          1027: 
        !          1028: report(sct)
        !          1029: int sct;
        !          1030: {
        !          1031:        if (Verbose>1)
        !          1032:                fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');
        !          1033: }
        !          1034: 
        !          1035: /*
        !          1036:  * if called as [-][dir/../]vrbCOMMAND set Verbose to 1
        !          1037:  * if called as [-][dir/../]rbCOMMAND set the pipe flag
        !          1038:  */
        !          1039: chkinvok(s)
        !          1040: char *s;
        !          1041: {
        !          1042:        register char *p;
        !          1043: 
        !          1044:        p = s;
        !          1045:        while (*p == '-')
        !          1046:                s = ++p;
        !          1047:        while (*p)
        !          1048:                if (*p++ == '/')
        !          1049:                        s = p;
        !          1050:        if (*s == 'v') {
        !          1051:                Verbose=1; ++s;
        !          1052:        }
        !          1053:        Progname = s;
        !          1054:        if (s[2] && s[0]=='r' && s[1]=='b')
        !          1055:                Topipe=TRUE;
        !          1056: }
        !          1057: 
        !          1058: checkpath(name)
        !          1059: char *name;
        !          1060: {
        !          1061:        if (Restricted) {
        !          1062:                if (fopen(name, "r") != NULL) {
        !          1063:                        canit();
        !          1064:                        fprintf(stderr, "\r\nrb: %s exists\n", name);
        !          1065:                        bibi();
        !          1066:                }
        !          1067:                /* restrict pathnames to current tree or uucppublic */
        !          1068:                if ( substr(name, "../")
        !          1069:                 || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
        !          1070:                        canit();
        !          1071:                        fprintf(stderr,"\r\nrb:\tSecurity Violation\r\n");
        !          1072:                        bibi();
        !          1073:                }
        !          1074:        }
        !          1075: }
        !          1076: 
        !          1077: SHAR_EOF
        !          1078: cat << \SHAR_EOF > rbsb.c
        !          1079: /* -rev 09-13-85
        !          1080:  * mode function and most of the rest of the system dependent
        !          1081:  * stuff for rb.c and sb.c   This file is #included so the includer
        !          1082:  * can set parameters such as HOWMANY.
        !          1083:  */
        !          1084: 
        !          1085: #ifdef USG
        !          1086: #include <sys/types.h>
        !          1087: #include <sys/stat.h>
        !          1088: #include <termio.h>
        !          1089: #include <sys/ioctl.h>
        !          1090: #define OS "USG"
        !          1091: #endif
        !          1092: 
        !          1093: #ifdef V7
        !          1094: #include <sys/types.h>
        !          1095: #include <sys/stat.h>
        !          1096: #include <sgtty.h>
        !          1097: #define OS "V7"
        !          1098: #endif
        !          1099: 
        !          1100: #ifndef OS
        !          1101: #include <termio.h>
        !          1102: #include <sys/ioctl.h>
        !          1103: #include <stat.h>
        !          1104: #define REGULUS
        !          1105: #define ONEREAD
        !          1106: #define OS "REGULUS"
        !          1107: #define void int
        !          1108: #define time_t long
        !          1109: #endif
        !          1110: 
        !          1111: 
        !          1112: #ifdef ICANON
        !          1113: struct termio oldtty, tty;
        !          1114: #else
        !          1115: struct sgttyb oldtty, tty;
        !          1116: struct tchars oldtch, tch;
        !          1117: #endif
        !          1118: 
        !          1119: int iofd = 0;          /* File descriptor for ioctls & reads */
        !          1120: 
        !          1121: /*
        !          1122:  * mode(n)
        !          1123:  *  2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g option
        !          1124:  *  1: save old tty stat, set raw mode 
        !          1125:  *  0: restore original tty mode
        !          1126:  */
        !          1127: mode(n)
        !          1128: {
        !          1129:        static did0 = FALSE;
        !          1130: 
        !          1131:        switch(n) {
        !          1132: #ifdef USG
        !          1133:        case 2: /* Cbreak mode used by sb when -g detected */
        !          1134:                if(!did0)
        !          1135:                        (void) ioctl(iofd, TCGETA, &oldtty);
        !          1136:                tty = oldtty;
        !          1137: 
        !          1138:                tty.c_iflag = BRKINT|IXON;
        !          1139: 
        !          1140:                tty.c_oflag = 0;        /* Transparent output */
        !          1141: 
        !          1142:                tty.c_cflag &= ~PARENB; /* Disable parity */
        !          1143:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !          1144: 
        !          1145: #ifdef XCLUDE
        !          1146:                tty.c_lflag = XCLUDE | ISIG;
        !          1147: #else
        !          1148:                tty.c_lflag = ISIG;
        !          1149: #endif
        !          1150: 
        !          1151:                tty.c_cc[VINTR] = 030;  /* Interrupt on CANCEL */
        !          1152:                tty.c_cc[VMIN] = 1;
        !          1153: 
        !          1154:                (void) ioctl(iofd, TCSETAW, &tty);
        !          1155:                did0 = TRUE;
        !          1156:                return OK;
        !          1157:        case 1:
        !          1158:                if(!did0)
        !          1159:                        (void) ioctl(iofd, TCGETA, &oldtty);
        !          1160:                tty = oldtty;
        !          1161: 
        !          1162:                tty.c_iflag = IGNBRK;
        !          1163: 
        !          1164:                 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
        !          1165:                tty.c_lflag &= ~(ECHO | ICANON | ISIG);
        !          1166: #ifdef XCLUDE
        !          1167:                tty.c_lflag |= XCLUDE;
        !          1168: #endif
        !          1169: 
        !          1170:                tty.c_oflag = 0;        /* Transparent output */
        !          1171: 
        !          1172:                tty.c_cflag &= ~PARENB; /* Leave baud rate alone, disable parity */
        !          1173:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !          1174:                tty.c_cc[VMIN] = HOWMANY; /* Satisfy reads when this many chars in */
        !          1175:                tty.c_cc[VTIME] = 1;    /* ... or in this many tenths of seconds */
        !          1176:                (void) ioctl(iofd, TCSETAW, &tty);
        !          1177:                did0 = TRUE;
        !          1178:                return OK;
        !          1179: #endif
        !          1180: #ifdef V7
        !          1181:        case 2:
        !          1182:                if(!did0) {
        !          1183:                        ioctl(iofd, TIOCEXCL, 0);
        !          1184:                        ioctl(iofd, TIOCGETP, &oldtty);
        !          1185:                        ioctl(iofd, TIOCGETC, &oldtch);
        !          1186:                }
        !          1187:                tty = oldtty;
        !          1188:                tch = oldtch;
        !          1189:                tch.t_intrc = 030;
        !          1190:                tty.sg_flags |= CBREAK;
        !          1191:                tty.sg_flags &= ~ECHO;
        !          1192:                ioctl(iofd, TIOCSETP, &tty);
        !          1193:                ioctl(iofd, TIOCSETC, &tch);
        !          1194:                did0 = TRUE;
        !          1195:                return OK;
        !          1196:        case 1:
        !          1197:                if(!did0) {
        !          1198:                        ioctl(iofd, TIOCEXCL, 0);
        !          1199:                        ioctl(iofd, TIOCGETP, &oldtty);
        !          1200:                        ioctl(iofd, TIOCGETC, &oldtch);
        !          1201:                }
        !          1202:                tty = oldtty;
        !          1203:                tty.sg_flags |= RAW;
        !          1204:                tty.sg_flags &= ~ECHO;
        !          1205:                ioctl(iofd, TIOCSETP, &tty);
        !          1206:                did0 = TRUE;
        !          1207:                return OK;
        !          1208: #endif
        !          1209: #ifdef REGULUS
        !          1210:        case 2:
        !          1211:                return ERROR;
        !          1212:        case 1:
        !          1213:                if(!did0) {
        !          1214:                        ioctl(iofd, TCGETA, &oldtty);
        !          1215:                }
        !          1216:                tty = oldtty;
        !          1217: 
        !          1218:                tty.c_lflag = 0;
        !          1219:                tty.c_iflag = IGNBRK;
        !          1220:                tty.c_oflag = 0;        /* Transparent output */
        !          1221: 
        !          1222:                tty.c_cflag &= ~PARENB; /* Leave baud rate alone, disable parity */
        !          1223:                tty.c_cflag |= CS8;     /* Set character size = 8 */
        !          1224:                tty.c_cc[VMIN] = HOWMANY; /* Satisfy reads when this many chars in */
        !          1225:                tty.c_cc[VTIME] = 1;    /* ... or in this many tenths of seconds */
        !          1226:                ioctl(iofd, TCSETA, &tty);
        !          1227:                did0 = TRUE;
        !          1228:                return OK;
        !          1229: #endif
        !          1230: #ifdef REGULUS10
        !          1231:                if(!did0) {
        !          1232:                        ioctl(iofd, TIOCGETP, &oldtty);
        !          1233:                }
        !          1234:                /* Sorry, No structure assignment in Regulus  C */
        !          1235:                movmem( (char *)&oldtty, (char *)&tty, sizeof(tty));
        !          1236:                tty.sg_flags |= (EIGHTBIT|RAW);
        !          1237:                tty.sg_flags &= ~ECHO;
        !          1238:                tty.sg_ledit &= ~LEDIT;
        !          1239:                ioctl(iofd, TIOCSETP, &tty);
        !          1240:                did0 = TRUE;
        !          1241:                return OK;
        !          1242: #endif
        !          1243:        case 0:
        !          1244:                if(!did0)
        !          1245:                        return ERROR;
        !          1246: #ifdef USG
        !          1247:                (void) ioctl(iofd, TCSBRK, 1);  /* Wait for output to drain */
        !          1248:                (void) ioctl(iofd, TCFLSH, 1);  /* Flush input queue */
        !          1249:                (void) ioctl(iofd, TCSETAW, &oldtty);   /* Restore original modes */
        !          1250:                (void) ioctl(iofd, TCXONC,1);   /* Restart output */
        !          1251: #endif
        !          1252: #ifdef V7
        !          1253:                ioctl(iofd, TIOCSETP, &oldtty);
        !          1254:                ioctl(iofd, TIOCSETC, &oldtch);
        !          1255:                ioctl(iofd, TIOCNXCL, 0);
        !          1256: #endif
        !          1257: #ifdef REGULUS
        !          1258:                ioctl(iofd, TCSETAW, &oldtty);  /* Restore original modes */
        !          1259: #endif
        !          1260: #ifdef REGULUS10
        !          1261:                ioctl(iofd, TIOCSETP, &oldtty);
        !          1262: #endif
        !          1263:                return OK;
        !          1264:        default:
        !          1265:                return ERROR;
        !          1266:        }
        !          1267: }
        !          1268: 
        !          1269: SHAR_EOF
        !          1270: cat << \SHAR_EOF > sb.1
        !          1271: '\" Revision Level 
        !          1272: '\" Last Delta     12-07-85
        !          1273: .TH SB 1 OMEN
        !          1274: .SH NAME
        !          1275: sb \- send files in batch mode
        !          1276: .SH SYNOPSIS
        !          1277: .B sb
        !          1278: [
        !          1279: .B \-1dfkquv
        !          1280: ]
        !          1281: .B file ...
        !          1282: .br
        !          1283: .B "sb -X"
        !          1284: [
        !          1285: .B \-1kquv
        !          1286: ]
        !          1287: .B file
        !          1288: .SH DESCRIPTION
        !          1289: .B Sb
        !          1290: sends one or more files with YMODEM batch protocol.
        !          1291: Normally, only the file name part of the pathname is transmitted.
        !          1292: On
        !          1293: .SM Unix
        !          1294: systems, additional information about the file is transmitted.
        !          1295: If the receiving program uses this information,
        !          1296: the transmitted file length controls the exact number of bytes written to
        !          1297: the output dataset,
        !          1298: and the modify time and file mode
        !          1299: are set accordingly.
        !          1300: 
        !          1301: With the
        !          1302: .B -X
        !          1303: flag,
        !          1304: .B sb
        !          1305: sends a single file using XMODEM protocol.
        !          1306: The received file name must be supplied by the user.
        !          1307: 
        !          1308: If sb is invoked with stdout and stderr to different datasets,
        !          1309: Verbose is set to 2, causing frame by frame progress reports
        !          1310: to stderr.
        !          1311: This may be disabled with the
        !          1312: .B q
        !          1313: option.
        !          1314: 
        !          1315: Iff sb is invoked with $SHELL set and iff that variable contains the
        !          1316: string
        !          1317: .I "rsh"
        !          1318: or
        !          1319: .I "rksh"
        !          1320: (restricted shell), sb operates in restricted mode.
        !          1321: Restricted mode restricts pathnames to the current directory and
        !          1322: PUBDIR (conventionally, /usr/spool/uucppublic) and/or subdirectories
        !          1323: thereof.
        !          1324: 
        !          1325: Sb supports YMODEM
        !          1326: .B g
        !          1327: mode by switching to "cbreak" tty mode with XON/XOFF folow control
        !          1328: and the interrupt character set to CAN.
        !          1329: The YMODEM
        !          1330: .B g
        !          1331: mode
        !          1332: (Pro-YAM
        !          1333: .B g
        !          1334: option)
        !          1335: increases throughput over error free channels
        !          1336: (direct connection, X.PC, etc.)
        !          1337: by not acknowledging each transmitted sector.
        !          1338: .PP
        !          1339: The meanings of the available options are:
        !          1340: .PP
        !          1341: .PD 0
        !          1342: .TP
        !          1343: .B 1
        !          1344: Use file descriptor 1 for ioctls and reads.
        !          1345: By default, file descriptor 0 is used.
        !          1346: .TP
        !          1347: .B X
        !          1348: (XMODEM protocol)
        !          1349: Send a single file without the filename packet.
        !          1350: .TP
        !          1351: .B d
        !          1352: Change all instances of "." to "/" in the transmitted pathname.
        !          1353: Thus, C.omenB0000 (which is unacceptable to MSDOS or CP/M)
        !          1354: is transmitted as C/omenB0000.
        !          1355: If the resultant filename has more than 8 characters in the stem,
        !          1356: a "." in inserted to allow a total of eleven.
        !          1357: .TP
        !          1358: .B f
        !          1359: Send Full pathnname.
        !          1360: Normally directory prefices are stripped from the transmitted
        !          1361: filename.
        !          1362: .TP
        !          1363: .B k
        !          1364: Send files using 1024 byte blocks
        !          1365: rather than the default 128 byte blocks.
        !          1366: The user should determine experimentally
        !          1367: the conditions under which use of 1k blocks
        !          1368: actually improves throughput without causing
        !          1369: problems.
        !          1370: .TP
        !          1371: .B q
        !          1372: Quiet suppresses verbosity.
        !          1373: .TP
        !          1374: .B u
        !          1375: Unlink the file after successful transmission.
        !          1376: .TP
        !          1377: .B v
        !          1378: .IR Verbose
        !          1379: causes a list of file
        !          1380: names to be appended to
        !          1381: /tmp/sblog .
        !          1382: More v's generate more output.
        !          1383: .PD
        !          1384: .SH EXAMPLES
        !          1385: (Unix command)
        !          1386: .RS
        !          1387: sb -k *.c
        !          1388: .br
        !          1389: .RE
        !          1390: (Pro-YAM command)
        !          1391: .RS
        !          1392: <F3>
        !          1393: .br
        !          1394: .RE
        !          1395: (8-bit YAM Commands)
        !          1396: .br
        !          1397: .RS
        !          1398: ^E
        !          1399: .br
        !          1400: >>>c: rt -y
        !          1401: .br
        !          1402: .RE
        !          1403: .SH SEE ALSO
        !          1404: rb(omen),
        !          1405: YMODEM.DOC,
        !          1406: Professional-YAM manual,
        !          1407: IMP(CP/M),
        !          1408: ncu(1),
        !          1409: sq(omen),
        !          1410: todos(omen),
        !          1411: tocpm(omen),
        !          1412: tomac(omen)
        !          1413: 
        !          1414: Compile time options for various operating systems are described in the
        !          1415: program source file.
        !          1416: .SH BUGS
        !          1417: On VMS,
        !          1418: some of the #includes with file names enclosed with angle brackets <>
        !          1419: may need to have the angle brackets removed, or vice versa.
        !          1420: 
        !          1421: The VMS version does not transmit the file date.
        !          1422: 
        !          1423: The VMS version does not recognize Pro-YAM\'s
        !          1424: .B g
        !          1425: option (YMODEM-g protocol).
        !          1426: 
        !          1427: The VMS version calculates the file length by counting the bytes therin.
        !          1428: 
        !          1429: When VMS is lightly loaded, the response time may be too quick for MODEM7
        !          1430: unless the MODEM7
        !          1431: .B "q"
        !          1432: modifier is used.
        !          1433: 
        !          1434: There may be unknown interactions between the VMS C standard i/o
        !          1435: package and RMS.
        !          1436: SHAR_EOF
        !          1437: cat << \SHAR_EOF > sb.c
        !          1438: #define VERSION "sb 2.24 01-04-86"
        !          1439: #define PUBDIR "/usr/spool/uucppublic"
        !          1440: 
        !          1441: /*% cc -K -O -DUSG sb.c -o sb
        !          1442: 
        !          1443:  * sb.c By Chuck Forsberg
        !          1444:  *
        !          1445:  *  USG UNIX (3.0) ioctl conventions courtesy  Jeff Martin
        !          1446:  *     cc -O -DV7  sb.c -o sb          Unix version 7, 2.8 - 4.3 BSD
        !          1447:  *     cc -O -DUSG sb.c -o sb          USG (3.0) Unix
        !          1448:  *  ******* Some systems (Venix, Coherent, Regulus) do not *******
        !          1449:  *  ******* support tty raw mode read(2) identically to    *******
        !          1450:  *  ******* Unix. ONEREAD must be defined to force one     *******
        !          1451:  *  ******* character reads for these systems.            *******
        !          1452:  *
        !          1453:  * A small program for Unix which can send 1 or more
        !          1454:  * files in Batch mode to computers running YAM. (Use "rb" in YAM.)
        !          1455:  * Supports the CRC option or regular checksum.
        !          1456:  * Exit status is 0 for all transfers completed successfully,
        !          1457:  * 1 for 1 or more unreadable files or'd with 200 for incomplete file xfer.
        !          1458:  *
        !          1459:  * accepts -k option for 1kb record length.
        !          1460:  *
        !          1461:  * sb is derived from yam2.c
        !          1462:  * Uses buffered i/o to reduce the CPU time compared to UMODEM.
        !          1463:  */
        !          1464: 
        !          1465: #define LOGFILE "/tmp/sblog"
        !          1466: 
        !          1467: #include <stdio.h>
        !          1468: #include <signal.h>
        !          1469: #include <setjmp.h>
        !          1470: #include <ctype.h>
        !          1471: 
        !          1472: #define PATHLEN 256
        !          1473: #define OK 0
        !          1474: #define FALSE 0
        !          1475: #define TRUE 1
        !          1476: #define ERROR (-1)
        !          1477: 
        !          1478: #define HOWMANY 2
        !          1479: #include "rbsb.c"      /* most of the system dependent stuff here */
        !          1480: 
        !          1481: FILE *in;
        !          1482: 
        !          1483: /* Ward Christensen / CP/M parameters - Don't change these! */
        !          1484: #define ENQ 005
        !          1485: #define CAN ('X'&037)
        !          1486: #define XOFF ('s'&037)
        !          1487: #define XON ('q'&037)
        !          1488: #define SOH 1
        !          1489: #define STX 2
        !          1490: #define EOT 4
        !          1491: #define ACK 6
        !          1492: #define NAK 025
        !          1493: #define CPMEOF 032
        !          1494: #define WANTCRC 0103   /* send C not NAK to get crc not checksum */
        !          1495: #define WANTG 0107     /* Send G not NAK to get nonstop batch xmsn */
        !          1496: #define TIMEOUT (-2)
        !          1497: #define RETRYMAX 10
        !          1498: #define SECSIZ 128     /* cp/m's Magic Number record size */
        !          1499: #define KSIZE 1024
        !          1500: 
        !          1501: char Lastrx;
        !          1502: char Crcflg;
        !          1503: int Wcsmask=0377;
        !          1504: int Verbose=0;
        !          1505: int Modem=0;           /* MODEM - don't send pathnames */
        !          1506: int Restricted=0;      /* restricted; no /.. or ../ in filenames */
        !          1507: int Quiet=0;           /* overrides logic that would otherwise set verbose */
        !          1508: int Fullname=0;                /* transmit full pathname */
        !          1509: int Unlinkafter=0;     /* Unlink file after it is sent */
        !          1510: int Dottoslash=0;      /* Change foo.bar.baz to foo/bar/baz */
        !          1511: int firstsec;
        !          1512: int errcnt=0;          /* number of files unreadable */
        !          1513: int blklen=SECSIZ;     /* length of transmitted records */
        !          1514: int Optiong;           /* Let it rip no wait for sector ACK's */
        !          1515: int Noeofseen;
        !          1516: int Totsecs;           /* total number of sectors this file */
        !          1517: char txbuf[KSIZE];
        !          1518: int Filcnt=0;          /* count of number of files opened */
        !          1519: 
        !          1520: jmp_buf tohere;                /* For the interrupt on RX timeout */
        !          1521: 
        !          1522: unsigned updcrc();
        !          1523: char *substr(), *getenv();
        !          1524: 
        !          1525: /* called by signal interrupt or terminate to clean things up */
        !          1526: bibi(n)
        !          1527: {
        !          1528:        canit(); fflush(stdout); mode(0);
        !          1529:        fprintf(stderr, "sb: caught signal %d; exiting\n", n);
        !          1530:        if (n == SIGQUIT)
        !          1531:                abort();
        !          1532:        exit(128+n);
        !          1533: }
        !          1534: 
        !          1535: #ifdef REGULUS
        !          1536: sendline(c)
        !          1537: {
        !          1538:        static char d[2];
        !          1539: 
        !          1540:        d[0] = c&Wcsmask;
        !          1541:        write(1, d, 1);
        !          1542: }
        !          1543: #else
        !          1544: #define sendline(c) putchar(c & Wcsmask)
        !          1545: #endif
        !          1546: 
        !          1547: main(argc, argv)
        !          1548: char *argv[];
        !          1549: {
        !          1550:        register char *cp;
        !          1551:        register npats;
        !          1552:        int agcnt; char **agcv;
        !          1553:        char **patts;
        !          1554:        int exitcode;
        !          1555: #ifndef REGULUS
        !          1556:        static char xXbuf[BUFSIZ];
        !          1557: #endif
        !          1558: 
        !          1559:        if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rsh")))
        !          1560:                Restricted=TRUE;
        !          1561: 
        !          1562:        npats=0;
        !          1563:        if (argc<2)
        !          1564:                usage();
        !          1565: #ifndef REGULUS
        !          1566:        setbuf(stdout, xXbuf);          
        !          1567: #endif
        !          1568:        while (--argc) {
        !          1569:                cp = *++argv;
        !          1570:                if (*cp++ == '-' && *cp) {
        !          1571:                        while ( *cp) {
        !          1572:                                switch(*cp++) {
        !          1573:                                case '1':
        !          1574:                                        iofd = 1; break;
        !          1575:                                case '7':
        !          1576:                                        Wcsmask=0177; break;
        !          1577:                                case 'd':
        !          1578:                                        ++Dottoslash;
        !          1579:                                        /* **** FALL THROUGH TO **** */
        !          1580:                                case 'f':
        !          1581:                                        Fullname=TRUE; break;
        !          1582:                                case 'k':
        !          1583:                                        blklen=KSIZE; break;
        !          1584:                                case 'q':
        !          1585:                                        Quiet=TRUE; Verbose=0; break;
        !          1586:                                case 'u':
        !          1587:                                        ++Unlinkafter; break;
        !          1588:                                case 'v':
        !          1589:                                        ++Verbose; break;
        !          1590:                                case 'X':
        !          1591:                                        ++Modem; break;
        !          1592:                                default:
        !          1593:                                        usage();
        !          1594:                                }
        !          1595:                        }
        !          1596:                }
        !          1597:                else if ( !npats && argc>0) {
        !          1598:                        if (argv[0][0]) {
        !          1599:                                npats=argc;
        !          1600:                                patts=argv;
        !          1601:                                if ( !strcmp(*patts, "-"))
        !          1602:                                        iofd = 1;
        !          1603:                        }
        !          1604:                }
        !          1605:        }
        !          1606:        if (npats < 1) 
        !          1607:                usage();
        !          1608:        if (Verbose) {
        !          1609:                if (freopen(LOGFILE, "a", stderr)==NULL) {
        !          1610:                        printf("Can't open log file %s\n",LOGFILE);
        !          1611:                        exit(0200);
        !          1612:                }
        !          1613:                setbuf(stderr, NULL);
        !          1614:        }
        !          1615:        if (fromcu() && !Quiet) {
        !          1616:                if (Verbose == 0)
        !          1617:                        Verbose = 2;
        !          1618:        }
        !          1619:        if (Verbose != 1) {
        !          1620:                fprintf(stderr, "sb: %d file%s requested:\r\n",
        !          1621:                 npats, npats>1?"s":"");
        !          1622:                for ( agcnt=npats, agcv=patts; --agcnt>=0; ) {
        !          1623:                        fprintf(stderr, "%s ", *agcv++);
        !          1624:                }
        !          1625:        }
        !          1626: 
        !          1627:        mode(1);
        !          1628:        if (signal(SIGINT, bibi) == SIG_IGN) {
        !          1629:                signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
        !          1630:        }
        !          1631:        else {
        !          1632:                signal(SIGINT, bibi); signal(SIGKILL, bibi);
        !          1633:                signal(SIGQUIT, bibi);
        !          1634:        }
        !          1635: 
        !          1636:        if (wcsend(npats, patts)==ERROR) {
        !          1637:                exitcode=0200;
        !          1638:                canit();
        !          1639:        }
        !          1640:        fflush(stdout);
        !          1641:        mode(0);
        !          1642:        exit((errcnt != 0) | exitcode);
        !          1643: }
        !          1644: 
        !          1645: wcsend(argc, argp)
        !          1646: char *argp[];
        !          1647: {
        !          1648:        register n;
        !          1649: 
        !          1650:        Crcflg=FALSE;
        !          1651:        firstsec=TRUE;
        !          1652:        for (n=0; n<argc; ++n) {
        !          1653:                Totsecs = 0;
        !          1654:                if (wcs(argp[n])==ERROR)
        !          1655:                        goto fubar;
        !          1656:        }
        !          1657:        Totsecs = 0;
        !          1658:        if (Filcnt==0) {        /* bitch if we couldn't open ANY files */
        !          1659:                fprintf(stderr,"\r\nCan't open any requested files.\n");
        !          1660:                return ERROR;
        !          1661:        }
        !          1662:        else if (wctxpn("")==ERROR)
        !          1663:                goto fubar;
        !          1664:        return OK;
        !          1665: fubar:
        !          1666:        canit(); return ERROR;
        !          1667: }
        !          1668: 
        !          1669: wcs(oname)
        !          1670: char *oname;
        !          1671: {
        !          1672:        register c;
        !          1673:        register char *p;
        !          1674:        struct stat f;
        !          1675:        char name[PATHLEN];
        !          1676: 
        !          1677:        strcpy(name, oname);
        !          1678: 
        !          1679:        if (Restricted) {
        !          1680:                /* restrict pathnames to current tree or uucppublic */
        !          1681:                if ( substr(name, "../")
        !          1682:                 || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
        !          1683:                        canit();
        !          1684:                        fprintf(stderr,"\r\nsb:\tSecurity Violation\r\n");
        !          1685:                        return ERROR;
        !          1686:                }
        !          1687:        }
        !          1688: 
        !          1689:        if ( !strcmp(oname, "-")) {
        !          1690:                sprintf(name, "s%d.sb", getpid());
        !          1691:                in = stdin;
        !          1692:        }
        !          1693:        else if ((in=fopen(oname, "r"))==NULL) {
        !          1694:                ++errcnt;
        !          1695:                return OK;      /* pass over it, there may be others */
        !          1696:        }
        !          1697:        ++Noeofseen;
        !          1698:        /* Check for directory or block special files */
        !          1699: #ifndef REGULUS                /* This doesn't seem to work on Regulus */
        !          1700:        fstat(fileno(in), &f);
        !          1701:        c = f.st_mode & S_IFMT;
        !          1702:        if (c == S_IFDIR || c == S_IFBLK) {
        !          1703:                fclose(in);
        !          1704:                return OK;
        !          1705:        }
        !          1706: #endif
        !          1707:        ++Filcnt;
        !          1708:        if (wctxpn(name)== ERROR)
        !          1709:                return ERROR;
        !          1710:        if (wctx()==ERROR)
        !          1711:                return ERROR;
        !          1712:        if (Unlinkafter)
        !          1713:                unlink(oname);
        !          1714:        return 0;
        !          1715: }
        !          1716: 
        !          1717: /*
        !          1718:  * generate and transmit pathname block consisting of
        !          1719:  *  pathname (null terminated),
        !          1720:  *  file length, mode time and file mode in octal
        !          1721:  *  as provided by the Unix fstat call.
        !          1722:  *  N.B.: modifies the passed name, may extend it!
        !          1723:  */
        !          1724: wctxpn(name)
        !          1725: char *name;
        !          1726: {
        !          1727:        register firstch;
        !          1728:        register char *p, *q;
        !          1729:        char name2[PATHLEN];
        !          1730:        struct stat f;
        !          1731: 
        !          1732:        if (Modem)
        !          1733:                return OK;
        !          1734:        logent("\r\nAwaiting pathname nak for %s\r\n", *name?name:"<END>");
        !          1735:        if (getnak())
        !          1736:                return ERROR;
        !          1737: 
        !          1738:        q = (char *) 0;
        !          1739:        if (Dottoslash) {               /* change . to . */
        !          1740:                for (p=name; *p; ++p) {
        !          1741:                        if (*p == '/')
        !          1742:                                q = p;
        !          1743:                        else if (*p == '.')
        !          1744:                                *(q=p) = '/';
        !          1745:                }
        !          1746:                if (q && strlen(++q) > 8) {     /* If name>8 chars */
        !          1747:                        q += 8;                 /*   make it .ext */
        !          1748:                        strcpy(name2, q);       /* save excess of name */
        !          1749:                        *q = '.';
        !          1750:                        strcpy(++q, name2);     /* add it back */
        !          1751:                }
        !          1752:        }
        !          1753: 
        !          1754:        for (p=name, q=txbuf ; *p; )
        !          1755:                if ((*q++ = *p++) == '/' && !Fullname)
        !          1756:                        q = txbuf;
        !          1757:        *q++ = 0;
        !          1758:        p=q;
        !          1759:        while (q < (txbuf + KSIZE))
        !          1760:                *q++ = 0;
        !          1761:        if (in == stdin)
        !          1762:                strcpy(p, "1999999999");
        !          1763: #ifndef REGULUS                /* This doesn't seem to work on Regulus */
        !          1764:        else if (*name && fstat(fileno(in), &f)!= -1)
        !          1765:                sprintf(p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);
        !          1766: #endif
        !          1767:        /* force 1k blocks if name won't fit in 128 byte block */
        !          1768:        if (txbuf[125])
        !          1769:                blklen=KSIZE;
        !          1770:        else {          /* A little goodie for IMP/KMD */
        !          1771:                txbuf[127] = f.st_size >>7;
        !          1772:                txbuf[126] = f.st_size >>15;
        !          1773:        }
        !          1774:        if (wcputsec(txbuf, 0, SECSIZ)==ERROR)
        !          1775:                return ERROR;
        !          1776:        return OK;
        !          1777: }
        !          1778: 
        !          1779: getnak()
        !          1780: {
        !          1781:        register firstch;
        !          1782: 
        !          1783:        Lastrx = 0;
        !          1784:        for (;;) {
        !          1785:                switch (firstch = readock(800,2)) {
        !          1786:                case TIMEOUT:
        !          1787:                        logent("Timeout on pathname\n");
        !          1788:                        return TRUE;
        !          1789:                case WANTG:
        !          1790:                        mode(2);        /* Set cbreak, XON/XOFF, etc. */
        !          1791:                        Optiong = TRUE;
        !          1792:                        blklen=KSIZE;
        !          1793:                case WANTCRC:
        !          1794:                        Crcflg = TRUE;
        !          1795:                case NAK:
        !          1796:                        return FALSE;
        !          1797:                case CAN:
        !          1798:                        if (Lastrx == CAN)
        !          1799:                                return TRUE;
        !          1800:                default:
        !          1801:                        break;
        !          1802:                }
        !          1803:                Lastrx = firstch;
        !          1804:        }
        !          1805: }
        !          1806: 
        !          1807: 
        !          1808: wctx()
        !          1809: {
        !          1810:        register int sectnum, attempts, firstch;
        !          1811: 
        !          1812:        firstsec=TRUE;
        !          1813: 
        !          1814:        while ((firstch=readock(400, 2))!=NAK && firstch != WANTCRC
        !          1815:          && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN)
        !          1816:                ;
        !          1817:        if (firstch==CAN) {
        !          1818:                logent("Receiver CANcelled\n");
        !          1819:                return ERROR;
        !          1820:        }
        !          1821:        if (firstch==WANTCRC)
        !          1822:                Crcflg=TRUE;
        !          1823:        if (firstch==WANTG)
        !          1824:                Crcflg=TRUE;
        !          1825:        sectnum=1;
        !          1826:        while (filbuf(txbuf, blklen)) {
        !          1827:                if (wcputsec(txbuf, sectnum, blklen)==ERROR) {
        !          1828:                        return ERROR;
        !          1829:                } else
        !          1830:                        sectnum++;
        !          1831:        }
        !          1832:        if (Verbose>1)
        !          1833:                fprintf(stderr, " Closing ");
        !          1834:        fclose(in);
        !          1835:        attempts=0;
        !          1836:        do {
        !          1837:                logent(" EOT ");
        !          1838:                purgeline();
        !          1839:                sendline(EOT);
        !          1840:                fflush(stdout);
        !          1841:                ++attempts;
        !          1842:        }
        !          1843:                while ((firstch=(readock(100, 2)) != ACK) && attempts < RETRYMAX);
        !          1844:        if (attempts == RETRYMAX) {
        !          1845:                logent("No ACK on EOT\n");
        !          1846:                return ERROR;
        !          1847:        }
        !          1848:        else
        !          1849:                return OK;
        !          1850: }
        !          1851: 
        !          1852: wcputsec(buf, sectnum, cseclen)
        !          1853: char *buf;
        !          1854: int sectnum;
        !          1855: int cseclen;   /* data length of this sector to send */
        !          1856: {
        !          1857:        register checksum, wcj;
        !          1858:        register char *cp;
        !          1859:        unsigned oldcrc;
        !          1860:        int firstch;
        !          1861:        int attempts;
        !          1862: 
        !          1863:        firstch=0;      /* part of logic to detect CAN CAN */
        !          1864: 
        !          1865:        if (Verbose>1)
        !          1866:                fprintf(stderr, "\rSector %3d %2dk ", Totsecs, Totsecs/8 );
        !          1867:        for (attempts=0; attempts <= RETRYMAX; attempts++) {
        !          1868:                Lastrx= firstch;
        !          1869:                sendline(cseclen==KSIZE?STX:SOH);
        !          1870:                sendline(sectnum);
        !          1871:                sendline(-sectnum -1);
        !          1872:                oldcrc=checksum=0;
        !          1873:                for (wcj=cseclen,cp=buf; --wcj>=0; ) {
        !          1874:                        sendline(*cp);
        !          1875:                        oldcrc=updcrc(*cp, oldcrc);
        !          1876:                        checksum += *cp++;
        !          1877:                }
        !          1878:                if (Crcflg) {
        !          1879:                        oldcrc=updcrc(0,updcrc(0,oldcrc));
        !          1880:                        sendline((int)oldcrc>>8);
        !          1881:                        sendline((int)oldcrc);
        !          1882:                }
        !          1883:                else
        !          1884:                        sendline(checksum);
        !          1885: 
        !          1886:                if (Optiong) {
        !          1887:                        firstsec = FALSE; return OK;
        !          1888:                }
        !          1889:                firstch = readock(400, (Noeofseen&&sectnum) ? 2:1);
        !          1890: gotnak:
        !          1891:                switch (firstch) {
        !          1892:                case CAN:
        !          1893:                        if(Lastrx == CAN) {
        !          1894: cancan:
        !          1895:                                logent("Cancelled\n");  return ERROR;
        !          1896:                        }
        !          1897:                        break;
        !          1898:                case TIMEOUT:
        !          1899:                        logent("Timeout on sector ACK\n"); continue;
        !          1900:                case WANTCRC:
        !          1901:                        if (firstsec)
        !          1902:                                Crcflg = TRUE;
        !          1903:                case NAK:
        !          1904:                        logent("NAK on sector\n"); continue;
        !          1905:                case ACK: 
        !          1906:                        firstsec=FALSE;
        !          1907:                        Totsecs += (cseclen>>7);
        !          1908:                        return OK;
        !          1909:                case ERROR:
        !          1910:                        logent("Got burst for sector ACK\n"); break;
        !          1911:                default:
        !          1912:                        logent("Got %02x for sector ACK\n", firstch); break;
        !          1913:                }
        !          1914:                for (;;) {
        !          1915:                        Lastrx = firstch;
        !          1916:                        if ((firstch = readock(400, 2)) == TIMEOUT)
        !          1917:                                break;
        !          1918:                        if (firstch == NAK || firstch == WANTCRC)
        !          1919:                                goto gotnak;
        !          1920:                        if (firstch == CAN && Lastrx == CAN)
        !          1921:                                goto cancan;
        !          1922:                }
        !          1923:        }
        !          1924:        logent("Retry Count Exceeded\n");
        !          1925:        return ERROR;
        !          1926: }
        !          1927: 
        !          1928: 
        !          1929: /* fill buf with count chars padding with ^Z for CPM */
        !          1930: filbuf(buf, count)
        !          1931: register char *buf;
        !          1932: {
        !          1933:        register c, m;
        !          1934:        static lfseen=0;
        !          1935: 
        !          1936:        m=count;
        !          1937:        while ((c=getc(in))!=EOF) {
        !          1938:                *buf++ =c;
        !          1939:                if (--m == 0)
        !          1940:                        break;
        !          1941:        }
        !          1942:        if (m==count)
        !          1943:                return (Noeofseen=0);
        !          1944:        else
        !          1945:                while (--m>=0)
        !          1946:                        *buf++ = CPMEOF;
        !          1947:        return count;
        !          1948: }
        !          1949: 
        !          1950: 
        !          1951: alrm()
        !          1952: {
        !          1953:        longjmp(tohere, -1);
        !          1954: }
        !          1955: 
        !          1956: 
        !          1957: /*
        !          1958:  * readock(timeout, count) reads character(s) from file descriptor 0
        !          1959:  *  (1 <= count <= 3)
        !          1960:  * it attempts to read count characters. If it gets more than one,
        !          1961:  * it is an error unless all are CAN
        !          1962:  * (otherwise, only normal response is ACK, CAN, or C)
        !          1963:  *  Only looks for one if Optiong, which signifies cbreak, not raw input
        !          1964:  *
        !          1965:  * timeout is in tenths of seconds
        !          1966:  */
        !          1967: readock(timeout, count)
        !          1968: {
        !          1969:        register int c;
        !          1970:        static char byt[5];
        !          1971: 
        !          1972:        if (Optiong)
        !          1973:                count = 1;      /* Special hack for cbreak */
        !          1974: 
        !          1975:        fflush(stdout);
        !          1976:        if (setjmp(tohere)) {
        !          1977:                logent("TIMEOUT\n");
        !          1978:                return TIMEOUT;
        !          1979:        }
        !          1980:        c = timeout/10;
        !          1981:        if (c<2)
        !          1982:                c=2;
        !          1983:        if (Verbose>3) {
        !          1984:                fprintf(stderr, "Timeout=%d Calling alarm(%d) ", timeout, c);
        !          1985:                byt[1] = 0;
        !          1986:        }
        !          1987:        signal(SIGALRM, alrm); alarm(c);
        !          1988: #ifdef ONEREAD
        !          1989:        c=read(iofd, byt, 1);           /* regulus raw read is unique */
        !          1990: #else
        !          1991:        c=read(iofd, byt, count);
        !          1992: #endif
        !          1993:        alarm(0);
        !          1994:        if (Verbose>5)
        !          1995:                fprintf(stderr, "ret cnt=%d %x %x\n", c, byt[0], byt[1]);
        !          1996:        if (c<1)
        !          1997:                return TIMEOUT;
        !          1998:        if (c==1)
        !          1999:                return (byt[0]&0377);
        !          2000:        else
        !          2001:                while (c)
        !          2002:                        if (byt[--c] != CAN)
        !          2003:                                return ERROR;
        !          2004:        return CAN;
        !          2005: }
        !          2006: 
        !          2007: purgeline()
        !          2008: {
        !          2009: #ifdef USG
        !          2010:        ioctl(iofd, TCFLSH, 0);
        !          2011: #else
        !          2012:        lseek(iofd, 0L, 2);
        !          2013: #endif
        !          2014: }
        !          2015: 
        !          2016: /* update CRC */
        !          2017: unsigned updcrc(c, crc)
        !          2018: register c;
        !          2019: register unsigned crc;
        !          2020: {
        !          2021:        register count;
        !          2022: 
        !          2023:        for (count=8; --count>=0;) {
        !          2024:                if (crc & 0x8000) {
        !          2025:                        crc <<= 1;
        !          2026:                        crc += (((c<<=1) & 0400)  !=  0);
        !          2027:                        crc ^= 0x1021;
        !          2028:                }
        !          2029:                else {
        !          2030:                        crc <<= 1;
        !          2031:                        crc += (((c<<=1) & 0400)  !=  0);
        !          2032:                }
        !          2033:        }
        !          2034:        return crc;     
        !          2035: }
        !          2036: 
        !          2037: /* send 10 CAN's to try to get the other end to shut up */
        !          2038: canit()
        !          2039: {
        !          2040:        register n;
        !          2041:        for (n=10; --n>=0; )
        !          2042:                sendline(CAN);
        !          2043: }
        !          2044: 
        !          2045: #ifdef REGULUS
        !          2046: /*
        !          2047:  * copies count bytes from s to d
        !          2048:  * (No structure assignment in Regulus C compiler)
        !          2049:  */
        !          2050: movmem(s, d, count)
        !          2051: register char *s, *d;
        !          2052: register count;
        !          2053: {
        !          2054:        while (--count >= 0)
        !          2055:                *d++ = *s++;
        !          2056: }
        !          2057: #endif
        !          2058: 
        !          2059: /*VARARGS1*/
        !          2060: logent(a, b, c)
        !          2061: char *a, *b, *c;
        !          2062: {
        !          2063:        if(Verbose)
        !          2064:                fprintf(stderr, a, b, c);
        !          2065: }
        !          2066: 
        !          2067: /*
        !          2068:  * return 1 iff stdout and stderr are different devices
        !          2069:  *  indicating this program operating with a modem on a
        !          2070:  *  different line
        !          2071:  */
        !          2072: fromcu()
        !          2073: {
        !          2074:        struct stat a, b;
        !          2075:        fstat(1, &a); fstat(2, &b);
        !          2076:        return (a.st_rdev != b.st_rdev);
        !          2077: }
        !          2078: 
        !          2079: /*
        !          2080:  * substr(string, token) searches for token in string s
        !          2081:  * returns pointer to token within string if found, NULL otherwise
        !          2082:  */
        !          2083: char *
        !          2084: substr(s, t)
        !          2085: register char *s,*t;
        !          2086: {
        !          2087:        register char *ss,*tt;
        !          2088:        /* search for first char of token */
        !          2089:        for (ss=s; *s; s++)
        !          2090:                if (*s == *t)
        !          2091:                        /* compare token with substring */
        !          2092:                        for (ss=s,tt=t; ;) {
        !          2093:                                if (*tt == 0)
        !          2094:                                        return s;
        !          2095:                                if (*ss++ != *tt++)
        !          2096:                                        break;
        !          2097:                        }
        !          2098:        return NULL;
        !          2099: }
        !          2100: 
        !          2101: usage()
        !          2102: {
        !          2103:        fprintf(stderr,"%s by Chuck Forsberg\n", VERSION);
        !          2104:        fprintf(stderr,"Usage: sb [-17dfkquvX] [-] file ...\n");
        !          2105:        fprintf(stderr,"        1 Use stdout for all modem i/o\n");
        !          2106:        fprintf(stderr,"        7 Use 7 bits only\n");
        !          2107:        fprintf(stderr,"        d Change '.' to '/' in pathnames\n");
        !          2108:        fprintf(stderr,"        f Send full pathname\n");
        !          2109:        fprintf(stderr,"        k Send 1024 byte packets\n");
        !          2110:        fprintf(stderr,"        q Quiet (no progress reports)\n");
        !          2111:        fprintf(stderr,"        u Unlink file after transmission\n");
        !          2112:        fprintf(stderr,"        v Verbose - give more information\n");
        !          2113:        fprintf(stderr,"        X XMODEM protocol - send no pathnames\n");
        !          2114:        fprintf(stderr,"- as pathname sends standard input, filename=sPID.sb, requires -1 flag\n");
        !          2115:        exit(1);
        !          2116: }
        !          2117: SHAR_EOF
        !          2118: cat << \SHAR_EOF > undos.1
        !          2119: .TH UNDOS 1 OMEN
        !          2120: .SH NAME
        !          2121: undos,tounix,todos,tocpm,tomac,unmac \- Change file format for target operating system
        !          2122: .SH SYNOPSIS
        !          2123: .B undos
        !          2124: [
        !          2125: .B -s
        !          2126: ]
        !          2127: file ...
        !          2128: .br
        !          2129: .B tounix
        !          2130: [
        !          2131: .B -s
        !          2132: ]
        !          2133: file ...
        !          2134: .br
        !          2135: .B todos
        !          2136: [
        !          2137: .B -s
        !          2138: ]
        !          2139: file ...
        !          2140: .br
        !          2141: .B tocpm
        !          2142: [
        !          2143: .B -s
        !          2144: ]
        !          2145: file ...
        !          2146: .br
        !          2147: .B unmac
        !          2148: [
        !          2149: .B -s
        !          2150: ]
        !          2151: file ...
        !          2152: .br
        !          2153: .B tomac
        !          2154: [
        !          2155: .B -s
        !          2156: ]
        !          2157: file ...
        !          2158: .SH DESCRIPTION
        !          2159: .B Undos
        !          2160: and
        !          2161: .B tounix
        !          2162: convert DOS or CP/M format source files to Unix format by deleting
        !          2163: carriage returns preceding linefeeds and eliminating characters
        !          2164: starting with CPMEOF (^Z).
        !          2165: .PP
        !          2166: .B Todos
        !          2167: converts Unix format source files to DOS format by adding a carriage return
        !          2168: (if not already present) before each linefeed,
        !          2169: and eliminates characters
        !          2170: starting with CPMEOF (^Z).
        !          2171: .B Tocpm
        !          2172: additionally appends CPMEOF (^Z) characters to the resulting file
        !          2173: to make the file length a multiple of the 128 byte CP/M record length.
        !          2174: 
        !          2175: Any combination of
        !          2176: .B undos, todos,
        !          2177: or
        !          2178: .B tocpm
        !          2179: (without flags)
        !          2180: may be applied to a proper ASCII
        !          2181: file without destroying information.
        !          2182: Lone carriage returns used to force overprinting are not translated
        !          2183: to CR/LF pairs.
        !          2184: 
        !          2185: .B Unmac
        !          2186: converts files with lines terminated only by carriage return
        !          2187: to Unix format.
        !          2188: .B Unmac
        !          2189: should only be used to translate files whose lines are terminated
        !          2190: by lone carriage returns.
        !          2191: 
        !          2192: .B Tomac
        !          2193: converts Unix format files to Macintosh format
        !          2194: (lines terminated by carriage return only).
        !          2195: 
        !          2196: The optional flag
        !          2197: .B -s
        !          2198: Strips the parity bit on all characters
        !          2199: and discards all resulting characters with values less than 7.
        !          2200: 
        !          2201: The access and modification times of the modified files are set
        !          2202: to those of the original files.
        !          2203: .SH DIAGNOSTICS
        !          2204: Refuses to translate files in which "binary" characters (less than 7
        !          2205: or greater than 127) are seen before CPMEOF.
        !          2206: Refuses to translate files
        !          2207: with ultra long lines.
        !          2208: Refuses to translate special files.
        !          2209: .SH NOTES
        !          2210: Should be executed with the current directory in the same filesystem
        !          2211: as the target files for minimum disk i/o.
        !          2212: .SH BUGS
        !          2213: Does not detect short files without linefeeds.
        !          2214: .B Unmac
        !          2215: and
        !          2216: .B tomac
        !          2217: cannot handle files with CR-only overprinting.
        !          2218: (Files whose lines end with CR only violate the ASCII code!).
        !          2219: .SH SEE ALSO
        !          2220: lar(1), yam(1), sq(1), usq(1), rb(omen), sb(omen)
        !          2221: SHAR_EOF
        !          2222: cat << \SHAR_EOF > undos.c
        !          2223: /*% cc -O -K % -o undos
        !          2224:  *
        !          2225:  * Undos - change DOS format files to Unix, etc.
        !          2226:  */
        !          2227: char ID[] =
        !          2228:  "Undos Rev 12-07-85 (C)Copyright Omen Technology Inc All Rights Reserved\n";
        !          2229: /*
        !          2230:  * This program and documentation may be copied, used, or modified
        !          2231:  *  by Professional-YAM and POWERCOMM licensees provided these notices are
        !          2232:  * not removed.  Others may use this program for non-profit purposes only.
        !          2233:  */
        !          2234: 
        !          2235: #include <stdio.h>
        !          2236: #include <sys/types.h>
        !          2237: #include <sys/stat.h>
        !          2238: 
        !          2239: #define LL 1024
        !          2240: #define SUB 032
        !          2241: 
        !          2242: char Lbuf[LL];
        !          2243: char *Progname;
        !          2244: int Todos = 0;
        !          2245: int Tocpm = 0;
        !          2246: int Tomac = 0;
        !          2247: int Unmac = 0;
        !          2248: int Strip = 0;
        !          2249: 
        !          2250: main(argc, argv)
        !          2251: char **argv;
        !          2252: {
        !          2253:        Progname = *argv;
        !          2254:        if (! strcmp(Progname, "tocpm"))
        !          2255:                Todos = Tocpm = 1;
        !          2256:        if (! strcmp(Progname, "todos"))
        !          2257:                Todos = 1;
        !          2258:        if (! strcmp(Progname, "unmac"))
        !          2259:                Unmac = 1;
        !          2260:        if (! strcmp(Progname, "tomac"))
        !          2261:                Tomac = 1;
        !          2262: 
        !          2263:        if (! strcmp(argv[1], "-s")) {
        !          2264:                ++Strip; --argc; ++argv;
        !          2265:        }
        !          2266: 
        !          2267: 
        !          2268:        if (argc<2 || *argv[1]== '-')
        !          2269:                usage();
        !          2270:        while (--argc >= 1)
        !          2271:                chngfmt(*++argv);
        !          2272:        exit(0);
        !          2273: }
        !          2274: usage()
        !          2275: {
        !          2276:        fprintf(stderr, ID);
        !          2277:        fprintf(stderr, "Usage: {undos|tounix|todos|tocpm|unmac} [-s] file ...\n");
        !          2278:        fprintf(stderr, "       -s Strip parity bit, ignore bytes < 007\n");
        !          2279:        exit(1);
        !          2280: }
        !          2281: 
        !          2282: 
        !          2283: chngfmt(name)
        !          2284: char *name;
        !          2285: {
        !          2286:        register c;
        !          2287:        register char *p;
        !          2288:        register n;
        !          2289:        register long fpos;
        !          2290:        struct stat st;
        !          2291:        FILE *fin, *fout;
        !          2292:        int linno = 0;
        !          2293:        long ftell();
        !          2294:        char *mktemp();
        !          2295:        char outnam[64];
        !          2296: 
        !          2297:        if (stat(name, &st)) {
        !          2298:                xperror(name); return;
        !          2299:        }
        !          2300:        if ((st.st_mode & S_IFMT) != S_IFREG) {
        !          2301:                fprintf(stderr, "%s: %s is not a regular file\n", Progname, name);
        !          2302:                return;
        !          2303:        }
        !          2304:        if ((fin = fopen(name, "r")) == NULL) {
        !          2305:                xperror(name); return;
        !          2306:        }
        !          2307:        strcpy(outnam, "undosXXXXXX");
        !          2308:        mktemp(outnam);
        !          2309:        if ((fout = fopen(outnam, "w")) == NULL) {
        !          2310:                xperror(outnam); exit(1);
        !          2311:        }
        !          2312: 
        !          2313:        for (;;) {
        !          2314:                ++linno;
        !          2315:                for (p=Lbuf, n=LL; --n>0; ) {
        !          2316: ignore:
        !          2317:                        if ((c = getc(fin)) == EOF)
        !          2318:                                break;
        !          2319:                        if ( !c)
        !          2320:                                goto ignore;
        !          2321:                        if (c < '\7' || (c & 0200)) {
        !          2322:                                if (Strip) {
        !          2323:                                        if ((c &= 0177) < 7)
        !          2324:                                                goto ignore;
        !          2325:                                } else
        !          2326:                                        goto thisbin; 
        !          2327:                        }
        !          2328:                        if (c == SUB)
        !          2329:                                break;
        !          2330:                        if (c == '\r' && Unmac)
        !          2331:                                c = '\n';
        !          2332:                        *p++ = c;
        !          2333:                        if (c == '\n')
        !          2334:                                break;
        !          2335:                }
        !          2336:                *p = '\0';
        !          2337: 
        !          2338:                if (n == 0) {
        !          2339:        thisbin:
        !          2340:                        if (n) {
        !          2341:                                fprintf(stderr, "%s: %s is a binary file", Progname, name);
        !          2342:                                fprintf(stderr, " line=%d char =%2X\n", linno, c);
        !          2343:                        } else
        !          2344:                                fprintf(stderr, "%s: %s has no linefeeds: try unmac?\n", Progname, name);
        !          2345:                        fclose(fout);
        !          2346:                        unlink(outnam);
        !          2347:                        return;
        !          2348:                }
        !          2349: 
        !          2350:                if (Todos) {
        !          2351:                        if (*--p == '\n' && p[-1] != '\r') {
        !          2352:                                *p++ = '\r'; *p++ = '\n'; *p = 0;
        !          2353:                        }
        !          2354:                } else if (Tomac) {
        !          2355:                        if (*--p == '\n') {
        !          2356:                                if (p[-1] == '\r')
        !          2357:                                        --p;
        !          2358:                                *p++ = '\r'; *p = 0;
        !          2359:                        }
        !          2360:                } else {
        !          2361:                        if (*--p == '\n' && *--p == '\r') {
        !          2362:                                *p++ = '\n'; *p = 0;
        !          2363:                        }
        !          2364:                }
        !          2365:                if (fputs(Lbuf, fout) == EOF) {
        !          2366:                        xperror(outnam); exit(1);
        !          2367:                }
        !          2368:                switch (c) {
        !          2369:                case EOF:
        !          2370:                        if (ferror(fin)) {
        !          2371:                                xperror(name); exit(0200);
        !          2372:                        }
        !          2373:                case SUB:
        !          2374:                        if (Tocpm) {
        !          2375:                                fpos = ftell(fout);
        !          2376:                                do {
        !          2377:                                        putc(SUB, fout);
        !          2378:                                } while (++fpos & 127);
        !          2379:                        }
        !          2380:                        fclose(fout); fclose(fin);
        !          2381:                        if (st.st_nlink > 1) 
        !          2382:                                sprintf(Lbuf, "cp %s %s", outnam, name);
        !          2383:                        else
        !          2384:                                sprintf(Lbuf, "mv %s %s", outnam, name);
        !          2385:                        system(Lbuf);
        !          2386:                        utime(name, (struct utimbuf *) &st.st_atime);
        !          2387:                        if (st.st_nlink > 1) 
        !          2388:                                unlink(outnam);
        !          2389:                        return;
        !          2390:                }
        !          2391:        }
        !          2392: }
        !          2393: 
        !          2394: xperror(s)
        !          2395: char *s;
        !          2396: {
        !          2397:        register char *p;
        !          2398:        extern int sys_nerr;
        !          2399:        extern char *sys_errlist[];
        !          2400:        extern errno;
        !          2401: 
        !          2402:        if (errno >= sys_nerr)
        !          2403:                p = "Gloryovsky: a New Error!";
        !          2404:        else
        !          2405:                p = sys_errlist[errno];
        !          2406:        fprintf(stderr, "%s: %s: %s\n", Progname, s, p);
        !          2407: }
        !          2408: SHAR_EOF
        !          2409: #      End of shell archive
        !          2410: exit 0

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.