# 2.11BSD#431 - /usr/src/local/zmodem/rz.c

##### Functions

    IsAnyLower        X
    ackbibi           X
    alrm              X
    bibi              X
    bttyout           X
    canit             X
    checkpath         X
    chkinvok          X
    closeit           X
    exec2             X
    flushmo           X
    getfree           X
    main              X
    make_dirs         X
    mkdir             X
    procheader        X
    purgeline         X
    putsec            X
    readline          X
    report            X
    rzfile            X
    rzfiles           X
    sendline          X
    substr            X
    sys2              X
    tryz              X
    uncaps            X
    usage             X
    vfile             X
    wcgetsec          X
    wcreceive         X
    wcrx              X
    wcrxpn            X
    zmputs            X
    zperr             X

##### Variables

    Batch             X
    Baudrate          X
    Blklen            X
    Bytesleft         X
    Crcflg            X
    Effbaud           X
    Eofseen           X
    Filemode          X
    Firstsec          X
    Lastrx            X
    Lleft             X
    Lzmanag           X
    MakeLCPathname    X
    Modtime           X
    Nflag             X
    Nozmodem          X
    Pathname          X
    Progname          X
    Quiet             X
    Readnum           X
    Restricted        X
    Rxascii           X
    Rxbinary          X
    Rxclob            X
    Thisbinary        X
    Topipe            X
    Verbose           X
    Zctlesc           X
    Zmodem            X
    Zrwindow          X
    chinseg           X
    errors            X
    linbuf            X
    rbmsg             X
    secbuf            X
    timep             X
    tohere            X
    tryzhdrtype       X
    zconv             X
    zmanag            X
    ztrans            X

##### Macros

    ACK               X
    BUFREAD           X
    CAN               X
    CPMEOF            X
    DEFBYTL           X
    ENQ               X
    EOT               X
    ERROR             X
    ERRORMAX          X
    FALSE             X
    GCOUNT            X
    HOWMANY           X
    LOGFILE           X
    NAK               X
    OK                X
    OS                X
    PATHLEN           X
    PROGNAME          X
    PUBDIR            X
    RCDO              X
    RETRYMAX          X
    SOH               X
    SS_NORMAL         X
    STX               X
    TERM_COREDUMP     X
    TERM_SIGNAL       X
    TERM_VALUE        X
    TIMEOUT           X
    TRUE              X
    UNIXFILE          X
    VERSION           X
    WANTCRC           X
    WCEOT             X
    XOFF              X
    XON               X
    xsendline         X

       1: #define VERSION "3.02 6-04-89"
       2: #define PUBDIR "/usr/spool/uucppublic"
       3:
       4: /*% cc -compat -M2 -Ox -K -i -DMD % -o rz; size rz;
       5: <-xtx-*> cc386 -Ox -DMD rz.c -o $B/rz;  size $B/rz
       6:  *
       7:  * rz.c By Chuck Forsberg
       8:  *
       9:  *	cc -O rz.c -o rz		USG (3.0) Unix
      10:  * 	cc -O -DV7  rz.c -o rz		Unix V7, BSD 2.8 - 4.3
      11:  *
      12:  *	ln rz rb;  ln rz rx			For either system
      13:  *
      14:  *	ln rz /usr/bin/rzrmail		For remote mail.  Make this the
      15:  *					login shell. rzrmail then calls
      16:  *					rmail(1) to deliver mail.
      17:  *
      18:  * To compile on VMS:
      19:  *
      20:  *	define LNK$LIBRARY   SYS$LIBRARY:VAXCRTL.OLB
      21:  *	cc rz.c
      22:  *	cc vvmodem.c
      23:  *	link rz,vvmodem
      24:  *	rz :== $disk:[username.subdir]rz.exe
      25:  *      For high speed, try increasing the SYSGEN parameter TTY_TYPAHDSZ to 256.
      26:  *
      27:  *
      28:  *  Unix is a trademark of Western Electric Company
      29:  *
      30:  * A program for Unix to receive files and commands from computers running
      31:  *  Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
      32:  *  rz uses Unix buffered input to reduce wasted CPU time.
      33:  *
      34:  *
      35:  *	This version implements numerous enhancements including ZMODEM
      36:  *	Run Length Encoding and variable length headers.  These
      37:  *	features were not funded by the original Telenet development
      38:  *	contract.
      39:  *
      40:  * This software may be freely used for non commercial and
      41:  * educational (didactic only) purposes.  This software may also
      42:  * be freely used to support file transfer operations to or from
      43:  * licensed Omen Technology products.  Any programs which use
      44:  * part or all of this software must be provided in source form
      45:  * with this notice intact except by written permission from Omen
      46:  * Technology Incorporated.
      47:  *
      48:  * Use of this software for commercial or administrative purposes
      49:  * except when exclusively limited to interfacing Omen Technology
      50:  * products requires a per port license payment of $20.00 US per
      51:  * port (less in quantity).  Use of this code by inclusion,
      52:  * decompilation, reverse engineering or any other means
      53:  * constitutes agreement to these conditions and acceptance of
      54:  * liability to license the materials and payment of reasonable
      55:  * legal costs necessary to enforce this license agreement.
      56:  *
      57:  *
      58:  *		Omen Technology Inc		FAX: 503-621-3745
      59:  *		Post Office Box 4681
      60:  *		Portland OR 97208
      61:  *
      62:  *	This code is made available in the hope it will be useful,
      63:  *	BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
      64:  *	DAMAGES OF ANY KIND.
      65:  *
      66:  *
      67:  *
      68:  * Iff the program is invoked by rzCOMMAND, output is piped to
      69:  * "COMMAND filename"  (Unix only)
      70:  *
      71:  *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
      72:  *  read(2) the same way as Unix. ONEREAD must be defined to force one
      73:  *  character reads for these systems. Added 7-01-84 CAF
      74:  *
      75:  *  Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF
      76:  *
      77:  *  BIX added 6-30-87 to support BIX(TM) upload protocol used by the
      78:  *  Byte Information Exchange.
      79:  *
      80:  *  NFGVMIN Updated 2-18-87 CAF for Xenix systems where c_cc[VMIN]
      81:  *  doesn't work properly (even though it compiles without error!),
      82:  *
      83:  *  SEGMENTS=n added 2-21-88 as a model for CP/M programs
      84:  *    for CP/M-80 systems that cannot overlap modem and disk I/O.
      85:  *
      86:  *  VMS flavor hacks begin with rz version 2.00
      87:  *
      88:  *  -DMD may be added to compiler command line to compile in
      89:  *    Directory-creating routines from Public Domain TAR by John Gilmore
      90:  *
      91:  *  HOWMANY may be tuned for best performance
      92:  *
      93:  *  USG UNIX (3.0) ioctl conventions courtesy  Jeff Martin
      94:  */
      95:
      96: #ifdef vax11c
      97: #include <types.h>
      98: #include <stat.h>
      99: #define LOGFILE "rzlog.tmp"
     100: #include <stdio.h>
     101: #include <signal.h>
     102: #include <setjmp.h>
     103: #include <ctype.h>
     104: #include <errno.h>
     105: #define OS "VMS"
     106: #define BUFREAD
     107: extern int errno;
     108: #define SS_NORMAL SS$_NORMAL
     109:
     110: #ifndef PROGNAME
     111: #define PROGNAME "rz"
     112: #endif
     113:
     114:
     115: #else
     116:
     117:
     118: #define SS_NORMAL 0
     119: #define LOGFILE "/tmp/rzlog"
     120: #include <stdio.h>
     121: #include <signal.h>
     122: #include <setjmp.h>
     123: #include <ctype.h>
     124: #include <errno.h>
     125: extern int errno;
     126: FILE *popen();
     127: #endif
     128:
     129: #define OK 0
     130: #define FALSE 0
     131: #define TRUE 1
     132: #define ERROR (-1)
     133:
     134: /*
     135:  * Max value for HOWMANY is 255.
     136:  *   A larger value reduces system overhead but may evoke kernel bugs.
     137:  *   133 corresponds to an XMODEM/CRC sector
     138:  */
     139: #ifndef HOWMANY
     140: #define HOWMANY 133
     141: #endif
     142:
     143: /* Ward Christensen / CP/M parameters - Don't change these! */
     144: #define ENQ 005
     145: #define CAN ('X'&037)
     146: #define XOFF ('s'&037)
     147: #define XON ('q'&037)
     148: #define SOH 1
     149: #define STX 2
     150: #define EOT 4
     151: #define ACK 6
     152: #define NAK 025
     153: #define CPMEOF 032
     154: #define WANTCRC 0103    /* send C not NAK to get crc not checksum */
     155: #define TIMEOUT (-2)
     156: #define RCDO (-3)
     157: #define GCOUNT (-4)
     158: #define ERRORMAX 5
     159: #define RETRYMAX 5
     160: #define WCEOT (-10)
     161: #define PATHLEN 257 /* ready for 4.2 bsd ? */
     162: #define UNIXFILE 0xF000 /* The S_IFMT file mask bit for stat */
     163:
     164: int Zmodem=0;       /* ZMODEM protocol requested */
     165: int Nozmodem = 0;   /* If invoked as "rb" */
     166: unsigned Baudrate = 2400;
     167: unsigned Effbaud = 2400;
     168: #ifdef vax11c
     169: #include "vrzsz.c"  /* most of the system dependent stuff here */
     170: #else
     171: #include "rbsb.c"   /* most of the system dependent stuff here */
     172: #endif
     173: #include "crctab.c"
     174:
     175: char *substr();
     176: FILE *fout;
     177:
     178: /*
     179:  * Routine to calculate the free bytes on the current file system
     180:  *  ~0 means many free bytes (unknown)
     181:  */
     182: long getfree()
     183: {
     184:     return(~0L);    /* many free bytes ... */
     185: }
     186:
     187: int Lastrx;
     188: int Crcflg;
     189: int Firstsec;
     190: int Eofseen;        /* indicates cpm eof (^Z) has been received */
     191: int errors;
     192: int Restricted=0;   /* restricted; no /.. or ../ in filenames */
     193: #ifdef ONEREAD
     194: /* Sorry, Regulus and some others don't work right in raw mode! */
     195: int Readnum = 1;    /* Number of bytes to ask for in read() from modem */
     196: #else
     197: int Readnum = HOWMANY;  /* Number of bytes to ask for in read() from modem */
     198: #endif
     199:
     200: #define DEFBYTL 2000000000L /* default rx file size */
     201: long Bytesleft;     /* number of bytes of incoming file left */
     202: long Modtime;       /* Unix style mod time for incoming file */
     203: int Filemode;       /* Unix style mode for incoming file */
     204: char Pathname[PATHLEN];
     205: char *Progname;     /* the name by which we were called */
     206:
     207: int Batch=0;
     208: int Topipe=0;
     209: int MakeLCPathname=TRUE;    /* make received pathname lower case */
     210: int Verbose=0;
     211: int Quiet=0;        /* overrides logic that would otherwise set verbose */
     212: int Nflag = 0;      /* Don't really transfer files */
     213: int Rxclob=FALSE;   /* Clobber existing file */
     214: int Rxbinary=FALSE; /* receive all files in bin mode */
     215: int Rxascii=FALSE;  /* receive files in ascii (translate) mode */
     216: int Thisbinary;     /* current file is to be received in bin mode */
     217: int Blklen;     /* record length of received packets */
     218:
     219: #ifdef SEGMENTS
     220: int chinseg = 0;    /* Number of characters received in this data seg */
     221: char secbuf[1+(SEGMENTS+1)*1024];
     222: #else
     223: char secbuf[1025];
     224: #endif
     225:
     226:
     227: char linbuf[HOWMANY];
     228: int Lleft=0;        /* number of characters in linbuf */
     229: time_t timep[2];
     230: char Lzmanag;       /* Local file management request */
     231: char zconv;     /* ZMODEM file conversion request */
     232: char zmanag;        /* ZMODEM file management request */
     233: char ztrans;        /* ZMODEM file transport request */
     234: int Zctlesc;        /* Encode control characters */
     235: int Zrwindow = 1400;    /* RX window size (controls garbage count) */
     236:
     237: jmp_buf tohere;     /* For the interrupt on RX timeout */
     238:
     239: #define xsendline(c) sendline(c)
     240:
     241: #include "zm.c"
     242:
     243: #include "zmr.c"
     244:
     245: int tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */
     246:
     247: alrm()
     248: {
     249:     longjmp(tohere, -1);
     250: }
     251:
     252: /* called by signal interrupt or terminate to clean things up */
     253: bibi(n)
     254: {
     255:     if (Zmodem)
     256:         zmputs(Attn);
     257:     canit(); mode(0);
     258:     fprintf(stderr, "rz: caught signal %d; exiting", n);
     259:     cucheck();
     260:     exit(128+n);
     261: }
     262:
     263: main(argc, argv)
     264: char *argv[];
     265: {
     266:     register char *cp;
     267:     register npats;
     268:     char *virgin, **patts;
     269:     char *getenv();
     270:     int exitcode;
     271:
     272:     Rxtimeout = 100;
     273:     setbuf(stderr, NULL);
     274:     if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
     275:         Restricted=TRUE;
     276:
     277:     from_cu();
     278: #ifdef vax11c
     279:     chkinvok(virgin = PROGNAME);
     280: #else
     281:     chkinvok(virgin=argv[0]);   /* if called as [-]rzCOMMAND set flag */
     282: #endif
     283:     npats = 0;
     284:     while (--argc) {
     285:         cp = *++argv;
     286:         if (*cp == '-') {
     287:             while( *++cp) {
     288:                 switch(*cp) {
     289:                 case '\\':
     290:                      cp[1] = toupper(cp[1]);  continue;
     291:                 case '+':
     292:                     Lzmanag = ZMAPND; break;
     293:                 case 'a':
     294:                     Rxascii=TRUE;  break;
     295:                 case 'b':
     296:                     Rxbinary=TRUE; break;
     297:                 case 'c':
     298:                     Crcflg=TRUE; break;
     299: #ifndef vax11c
     300:                 case 'D':
     301:                     Nflag = TRUE; break;
     302: #endif
     303:                 case 'e':
     304:                     Zctlesc = 1; break;
     305:                 case 'p':
     306:                     Lzmanag = ZMPROT;  break;
     307:                 case 'q':
     308:                     Quiet=TRUE; Verbose=0; break;
     309:                 case 't':
     310:                     if (--argc < 1) {
     311:                         usage();
     312:                     }
     313:                     Rxtimeout = atoi(*++argv);
     314:                     if (Rxtimeout<10 || Rxtimeout>1000)
     315:                         usage();
     316:                     break;
     317:                 case 'w':
     318:                     if (--argc < 1) {
     319:                         usage();
     320:                     }
     321:                     Zrwindow = atoi(*++argv);
     322:                     break;
     323:                 case 'u':
     324:                     MakeLCPathname=FALSE; break;
     325:                 case 'v':
     326:                     ++Verbose; break;
     327:                 case 'y':
     328:                     Rxclob=TRUE; break;
     329:                 default:
     330:                     usage();
     331:                 }
     332:             }
     333:         }
     334:         else if ( !npats && argc>0) {
     335:             if (argv[0][0]) {
     336:                 npats=argc;
     337:                 patts=argv;
     338:             }
     339:         }
     340:     }
     341:     if (npats > 1)
     342:         usage();
     343:     if (Batch && npats)
     344:         usage();
     345:     if (Verbose) {
     346:         if (freopen(LOGFILE, "a", stderr)==NULL) {
     347:             printf("Can't open log file %s\n",LOGFILE);
     348:             exit(0200);
     349:         }
     350:         setbuf(stderr, NULL);
     351:         fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname);
     352:     }
     353:     if (Fromcu && !Quiet) {
     354:         if (Verbose == 0)
     355:             Verbose = 2;
     356:     }
     357:     vfile("%s %s for %s\n", Progname, VERSION, OS);
     358:     mode(1);
     359:     if (signal(SIGINT, bibi) == SIG_IGN) {
     360:         signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
     361:     }
     362:     else {
     363:         signal(SIGINT, bibi); signal(SIGKILL, bibi);
     364:     }
     365:     signal(SIGTERM, bibi);
     366:     if (wcreceive(npats, patts)==ERROR) {
     367:         exitcode=0200;
     368:         canit();
     369:     }
     370:     mode(0);
     371:     if (exitcode && !Zmodem)    /* bellow again with all thy might. */
     372:         canit();
     373:     if (exitcode)
     374:         cucheck();
     375:     exit(exitcode ? exitcode:SS_NORMAL);
     376: }
     377:
     378:
     379: usage()
     380: {
     381:     cucheck();
     382:     fprintf(stderr,"Usage:	rz [-abeuvy]		(ZMODEM)\n");
     383:     fprintf(stderr,"or	rb [-abuvy]		(YMODEM)\n");
     384:     fprintf(stderr,"or	rx [-abcv] file	(XMODEM or XMODEM-1k)\n");
     385:     fprintf(stderr,"	  -a ASCII transfer (strip CR)\n");
     386:     fprintf(stderr,"	  -b Binary transfer for all files\n");
     387: #ifndef vax11c
     388:     fprintf(stderr,"	  -c Use 16 bit CRC	(XMODEM)\n");
     389: #endif
     390:     fprintf(stderr,"	  -e Escape control characters	(ZMODEM)\n");
     391:     fprintf(stderr,"	  -v Verbose more v's give more info\n");
     392:     fprintf(stderr,"	  -y Yes, clobber existing file if any\n");
     393:     fprintf(stderr,"%s %s for %s by Chuck Forsberg, Omen Technology INC\n",
     394:       Progname, VERSION, OS);
     395:     fprintf(stderr, "\t\t\042The High Reliability Software\042\n");
     396:     exit(SS_NORMAL);
     397: }
     398: /*
     399:  *  Debugging information output interface routine
     400:  */
     401: /* VARARGS1 */
     402: vfile(f, a, b, c, d)
     403: long a, b, c, d;
     404: {
     405:     if (Verbose > 2) {
     406:         fprintf(stderr, f, a, b, c, d);
     407:         fprintf(stderr, "\n");
     408:     }
     409: }
     410:
     411: /*
     412:  * Let's receive something already.
     413:  */
     414:
     415: char *rbmsg =
     416: "%s ready. To begin transfer, type \"%s file ...\" to your modem program\r\n\n";
     417:
     418: wcreceive(argc, argp)
     419: char **argp;
     420: {
     421:     register c;
     422:
     423:     if (Batch || argc==0) {
     424:         Crcflg=1;
     425:         if ( !Quiet)
     426:             fprintf(stderr, rbmsg, Progname, Nozmodem?"sb":"sz");
     427:         if (c=tryz()) {
     428:             if (c == ZCOMPL)
     429:                 return OK;
     430:             if (c == ERROR)
     431:                 goto fubar;
     432:             c = rzfiles();
     433:             if (c)
     434:                 goto fubar;
     435:         } else {
     436:             for (;;) {
     437:                 if (wcrxpn(secbuf)== ERROR)
     438:                     goto fubar;
     439:                 if (secbuf[0]==0)
     440:                     return OK;
     441:                 if (procheader(secbuf) == ERROR)
     442:                     goto fubar;
     443:                 if (wcrx()==ERROR)
     444:                     goto fubar;
     445:             }
     446:         }
     447:     } else {
     448:         Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
     449:
     450:         procheader(""); strcpy(Pathname, *argp); checkpath(Pathname);
     451:         fprintf(stderr, "\nrz: ready to receive %s\r\n", Pathname);
     452:         if ((fout=fopen(Pathname, "w")) == NULL)
     453:             return ERROR;
     454:         if (wcrx()==ERROR)
     455:             goto fubar;
     456:     }
     457:     return OK;
     458: fubar:
     459:     canit();
     460: #ifndef vax11c
     461:     if (Topipe && fout) {
     462:         pclose(fout);  return ERROR;
     463:     }
     464: #endif
     465:     Modtime = 1;
     466:     if (fout)
     467:         fclose(fout);
     468: #ifndef vax11c
     469:     if (Restricted) {
     470:         unlink(Pathname);
     471:         fprintf(stderr, "\r\nrz: %s removed.\r\n", Pathname);
     472:     }
     473: #endif
     474:     return ERROR;
     475: }
     476:
     477:
     478: /*
     479:  * Fetch a pathname from the other end as a C ctyle ASCIZ string.
     480:  * Length is indeterminate as long as less than Blklen
     481:  * A null string represents no more files (YMODEM)
     482:  */
     483: wcrxpn(rpn)
     484: char *rpn;  /* receive a pathname */
     485: {
     486:     register c;
     487:
     488: #ifdef NFGVMIN
     489:     readline(1);
     490: #else
     491:     purgeline();
     492: #endif
     493:
     494: et_tu:
     495:     Firstsec=TRUE;  Eofseen=FALSE;
     496:     sendline(Crcflg?WANTCRC:NAK);
     497:     Lleft=0;    /* Do read next time ... */
     498:     while ((c = wcgetsec(rpn, 100)) != 0) {
     499:         if (c == WCEOT) {
     500:             zperr( "Pathname fetch returned %d", c);
     501:             sendline(ACK);
     502:             Lleft=0;    /* Do read next time ... */
     503:             readline(1);
     504:             goto et_tu;
     505:         }
     506:         return ERROR;
     507:     }
     508:     sendline(ACK);
     509:     return OK;
     510: }
     511:
     512: /*
     513:  * Adapted from CMODEM13.C, written by
     514:  * Jack M. Wierda and Roderick W. Hart
     515:  */
     516:
     517: wcrx()
     518: {
     519:     register int sectnum, sectcurr;
     520:     register char sendchar;
     521:     register char *p;
     522:     int cblklen;            /* bytes to dump this block */
     523:
     524:     Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
     525:     sendchar=Crcflg?WANTCRC:NAK;
     526:
     527:     for (;;) {
     528:         sendline(sendchar); /* send it now, we're ready! */
     529:         Lleft=0;    /* Do read next time ... */
     530:         sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
     531:         report(sectcurr);
     532:         if (sectcurr==(sectnum+1 &0377)) {
     533:             sectnum++;
     534:             cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
     535:             if (putsec(secbuf, cblklen)==ERROR)
     536:                 return ERROR;
     537:             if ((Bytesleft-=cblklen) < 0)
     538:                 Bytesleft = 0;
     539:             sendchar=ACK;
     540:         }
     541:         else if (sectcurr==(sectnum&0377)) {
     542:             zperr( "Received dup Sector");
     543:             sendchar=ACK;
     544:         }
     545:         else if (sectcurr==WCEOT) {
     546:             if (closeit())
     547:                 return ERROR;
     548:             sendline(ACK);
     549:             Lleft=0;    /* Do read next time ... */
     550:             return OK;
     551:         }
     552:         else if (sectcurr==ERROR)
     553:             return ERROR;
     554:         else {
     555:             zperr( "Sync Error");
     556:             return ERROR;
     557:         }
     558:     }
     559: }
     560:
     561: /*
     562:  * Wcgetsec fetches a Ward Christensen type sector.
     563:  * Returns sector number encountered or ERROR if valid sector not received,
     564:  * or CAN CAN received
     565:  * or WCEOT if eot sector
     566:  * time is timeout for first char, set to 4 seconds thereafter
     567:  ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
     568:  *    (Caller must do that when he is good and ready to get next sector)
     569:  */
     570:
     571: wcgetsec(rxbuf, maxtime)
     572: char *rxbuf;
     573: int maxtime;
     574: {
     575:     register checksum, wcj, firstch;
     576:     register unsigned short oldcrc;
     577:     register char *p;
     578:     int sectcurr;
     579:
     580:     for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
     581:
     582:         if ((firstch=readline(maxtime))==STX) {
     583:             Blklen=1024; goto get2;
     584:         }
     585:         if (firstch==SOH) {
     586:             Blklen=128;
     587: get2:
     588:             sectcurr=readline(1);
     589:             if ((sectcurr+(oldcrc=readline(1)))==0377) {
     590:                 oldcrc=checksum=0;
     591:                 for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
     592:                     if ((firstch=readline(1)) < 0)
     593:                         goto bilge;
     594:                     oldcrc=updcrc(firstch, oldcrc);
     595:                     checksum += (*p++ = firstch);
     596:                 }
     597:                 if ((firstch=readline(1)) < 0)
     598:                     goto bilge;
     599:                 if (Crcflg) {
     600:                     oldcrc=updcrc(firstch, oldcrc);
     601:                     if ((firstch=readline(1)) < 0)
     602:                         goto bilge;
     603:                     oldcrc=updcrc(firstch, oldcrc);
     604:                     if (oldcrc & 0xFFFF)
     605:                         zperr( "CRC");
     606:                     else {
     607:                         Firstsec=FALSE;
     608:                         return sectcurr;
     609:                     }
     610:                 }
     611:                 else if (((checksum-firstch)&0377)==0) {
     612:                     Firstsec=FALSE;
     613:                     return sectcurr;
     614:                 }
     615:                 else
     616:                     zperr( "Checksum");
     617:             }
     618:             else
     619:                 zperr("Sector number garbled");
     620:         }
     621:         /* make sure eot really is eot and not just mixmash */
     622: #ifdef NFGVMIN
     623:         else if (firstch==EOT && readline(1)==TIMEOUT)
     624:             return WCEOT;
     625: #else
     626:         else if (firstch==EOT && Lleft==0)
     627:             return WCEOT;
     628: #endif
     629:         else if (firstch==CAN) {
     630:             if (Lastrx==CAN) {
     631:                 zperr( "Sender CANcelled");
     632:                 return ERROR;
     633:             } else {
     634:                 Lastrx=CAN;
     635:                 continue;
     636:             }
     637:         }
     638:         else if (firstch==TIMEOUT) {
     639:             if (Firstsec)
     640:                 goto humbug;
     641: bilge:
     642:             zperr( "TIMEOUT");
     643:         }
     644:         else
     645:             zperr( "Got 0%o sector header", firstch);
     646:
     647: humbug:
     648:         Lastrx=0;
     649:         while(readline(1)!=TIMEOUT)
     650:             ;
     651:         if (Firstsec) {
     652:             sendline(Crcflg?WANTCRC:NAK);
     653:             Lleft=0;    /* Do read next time ... */
     654:         } else {
     655:             maxtime=40; sendline(NAK);
     656:             Lleft=0;    /* Do read next time ... */
     657:         }
     658:     }
     659:     /* try to stop the bubble machine. */
     660:     canit();
     661:     return ERROR;
     662: }
     663:
     664: #ifndef vax11c
     665: /*
     666:  * This version of readline is reasoably well suited for
     667:  * reading many characters.
     668:  *  (except, currently, for the Regulus version!)
     669:  *
     670:  * timeout is in tenths of seconds
     671:  */
     672: readline(timeout)
     673: int timeout;
     674: {
     675:     register n;
     676:     static char *cdq;   /* pointer for removing chars from linbuf */
     677:
     678:     if (--Lleft >= 0) {
     679:         if (Verbose > 8) {
     680:             fprintf(stderr, "%02x ", *cdq&0377);
     681:         }
     682:         return (*cdq++ & 0377);
     683:     }
     684:     n = timeout/10;
     685:     if (n < 2)
     686:         n = 3;
     687:     if (Verbose > 5)
     688:         fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",
     689:           n, Readnum);
     690:     if (setjmp(tohere)) {
     691: #ifdef TIOCFLUSH
     692: /*		ioctl(0, TIOCFLUSH, 0); */
     693: #endif
     694:         Lleft = 0;
     695:         if (Verbose>1)
     696:             fprintf(stderr, "Readline:TIMEOUT\n");
     697:         return TIMEOUT;
     698:     }
     699:     signal(SIGALRM, alrm); alarm(n);
     700:     Lleft=read(0, cdq=linbuf, Readnum);
     701:     alarm(0);
     702:     if (Verbose > 5) {
     703:         fprintf(stderr, "Read returned %d bytes\n", Lleft);
     704:     }
     705:     if (Lleft < 1)
     706:         return TIMEOUT;
     707:     --Lleft;
     708:     if (Verbose > 8) {
     709:         fprintf(stderr, "%02x ", *cdq&0377);
     710:     }
     711:     return (*cdq++ & 0377);
     712: }
     713:
     714:
     715:
     716: /*
     717:  * Purge the modem input queue of all characters
     718:  */
     719: purgeline()
     720: {
     721:     Lleft = 0;
     722: #ifdef USG
     723:     ioctl(0, TCFLSH, 0);
     724: #else
     725:     lseek(0, 0L, 2);
     726: #endif
     727: }
     728: #endif
     729:
     730:
     731: /*
     732:  * Process incoming file information header
     733:  */
     734: procheader(name)
     735: char *name;
     736: {
     737:     register char *openmode, *p, **pp;
     738:
     739:     /* set default parameters and overrides */
     740:     openmode = "w";
     741:     Thisbinary = (!Rxascii) || Rxbinary;
     742:     if (Lzmanag)
     743:         zmanag = Lzmanag;
     744:
     745:     /*
     746: 	 *  Process ZMODEM remote file management requests
     747: 	 */
     748:     if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
     749:         Thisbinary = 0;
     750:     if (zconv == ZCBIN) /* Remote Binary override */
     751:         Thisbinary = TRUE;
     752:     else if (zmanag == ZMAPND)
     753:         openmode = "a";
     754:
     755: #ifndef BIX
     756:     /* Check for existing file */
     757:     if (!Rxclob && (zmanag&ZMMASK) != ZMCLOB && (fout=fopen(name, "r"))) {
     758:         fclose(fout);  return ERROR;
     759:     }
     760: #endif
     761:
     762:     Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
     763:
     764:     p = name + 1 + strlen(name);
     765:     if (*p) {   /* file coming from Unix or DOS system */
     766:         sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
     767: #ifndef vax11c
     768:         if (Filemode & UNIXFILE)
     769:             ++Thisbinary;
     770: #endif
     771:         if (Verbose) {
     772:             fprintf(stderr,  "Incoming: %s %ld %lo %o\n",
     773:               name, Bytesleft, Modtime, Filemode);
     774:         }
     775:     }
     776:
     777: #ifdef BIX
     778:     if ((fout=fopen("scratchpad", openmode)) == NULL)
     779:         return ERROR;
     780:     return OK;
     781: #else
     782:
     783:     else {      /* File coming from CP/M system */
     784:         for (p=name; *p; ++p)       /* change / to _ */
     785:             if ( *p == '/')
     786:                 *p = '_';
     787:
     788:         if ( *--p == '.')       /* zap trailing period */
     789:             *p = 0;
     790:     }
     791:
     792: #ifndef vax11c
     793:     if (!Zmodem && MakeLCPathname && !IsAnyLower(name)
     794:       && !(Filemode&UNIXFILE))
     795:         uncaps(name);
     796: #endif
     797:     if (Topipe > 0) {
     798:         sprintf(Pathname, "%s %s", Progname+2, name);
     799:         if (Verbose)
     800:             fprintf(stderr,  "Topipe: %s %s\n",
     801:               Pathname, Thisbinary?"BIN":"ASCII");
     802: #ifndef vax11c
     803:         if ((fout=popen(Pathname, "w")) == NULL)
     804:             return ERROR;
     805: #endif
     806:     } else {
     807:         strcpy(Pathname, name);
     808:         if (Verbose) {
     809:             fprintf(stderr,  "Receiving %s %s %s\n",
     810:               name, Thisbinary?"BIN":"ASCII", openmode);
     811:         }
     812:         checkpath(name);
     813:         if (Nflag)
     814:             name = "/dev/null";
     815: #ifndef vax11c
     816:         if (name[0] == '!' || name[0] == '|') {
     817:             if ( !(fout = popen(name+1, "w"))) {
     818:                 return ERROR;
     819:             }
     820:             Topipe = -1;  return(OK);
     821:         }
     822: #endif
     823: #ifdef MD
     824:         fout = fopen(name, openmode);
     825:         if ( !fout)
     826:             if (make_dirs(name))
     827:                 fout = fopen(name, openmode);
     828: #else
     829:         fout = fopen(name, openmode);
     830: #endif
     831:         if ( !fout)
     832:             return ERROR;
     833:     }
     834:     return OK;
     835: #endif /* BIX */
     836: }
     837:
     838: #ifdef MD
     839: /*
     840:  *  Directory-creating routines from Public Domain TAR by John Gilmore
     841:  */
     842:
     843: /*
     844:  * After a file/link/symlink/dir creation has failed, see if
     845:  * it's because some required directory was not present, and if
     846:  * so, create all required dirs.
     847:  */
     848: make_dirs(pathname)
     849: register char *pathname;
     850: {
     851:     register char *p;       /* Points into path */
     852:     int madeone = 0;        /* Did we do anything yet? */
     853:     int save_errno = errno;     /* Remember caller's errno */
     854:     char *strchr();
     855:
     856:     if (errno != ENOENT)
     857:         return 0;       /* Not our problem */
     858:
     859:     for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {
     860:         /* Avoid mkdir of empty string, if leading or double '/' */
     861:         if (p == pathname || p[-1] == '/')
     862:             continue;
     863:         /* Avoid mkdir where last part of path is '.' */
     864:         if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
     865:             continue;
     866:         *p = 0;             /* Truncate the path there */
     867:         if ( !mkdir(pathname, 0777)) {  /* Try to create it as a dir */
     868:             vfile("Made directory %s\n", pathname);
     869:             madeone++;      /* Remember if we made one */
     870:             *p = '/';
     871:             continue;
     872:         }
     873:         *p = '/';
     874:         if (errno == EEXIST)        /* Directory already exists */
     875:             continue;
     876:         /*
     877: 		 * Some other error in the mkdir.  We return to the caller.
     878: 		 */
     879:         break;
     880:     }
     881:     errno = save_errno;     /* Restore caller's errno */
     882:     return madeone;         /* Tell them to retry if we made one */
     883: }
     884:
     885: #if (MD != 2)
     886: #define TERM_SIGNAL(status) ((status) & 0x7F)
     887: #define TERM_COREDUMP(status)   (((status) & 0x80) != 0)
     888: #define TERM_VALUE(status)  ((status) >> 8)
     889: /*
     890:  * Make a directory.  Compatible with the mkdir() system call on 4.2BSD.
     891:  */
     892: mkdir(dpath, dmode)
     893: char *dpath;
     894: int dmode;
     895: {
     896:     int cpid, status;
     897:     struct stat statbuf;
     898:
     899:     if (stat(dpath,&statbuf) == 0) {
     900:         errno = EEXIST;     /* Stat worked, so it already exists */
     901:         return -1;
     902:     }
     903:
     904:     /* If stat fails for a reason other than non-existence, return error */
     905:     if (errno != ENOENT) return -1;
     906:
     907:     switch (cpid = fork()) {
     908:
     909:     case -1:            /* Error in fork() */
     910:         return(-1);     /* Errno is set already */
     911:
     912:     case 0:             /* Child process */
     913:         /*
     914: 		 * Cheap hack to set mode of new directory.  Since this
     915: 		 * child process is going away anyway, we zap its umask.
     916: 		 * FIXME, this won't suffice to set SUID, SGID, etc. on this
     917: 		 * directory.  Does anybody care?
     918: 		 */
     919:         status = umask(0);  /* Get current umask */
     920:         status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
     921:         execl("/bin/mkdir", "mkdir", dpath, (char *)0);
     922:         _exit(-1);      /* Can't exec /bin/mkdir */
     923:
     924:     default:            /* Parent process */
     925:         while (cpid != wait(&status)) ; /* Wait for kid to finish */
     926:     }
     927:
     928:     if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {
     929:         errno = EIO;        /* We don't know why, but */
     930:         return -1;      /* /bin/mkdir failed */
     931:     }
     932:
     933:     return 0;
     934: }
     935: #endif /* MD != 2 */
     936: #endif /* MD */
     937:
     938: /*
     939:  * Putsec writes the n characters of buf to receive file fout.
     940:  *  If not in binary mode, carriage returns, and all characters
     941:  *  starting with CPMEOF are discarded.
     942:  */
     943: putsec(buf, n)
     944: char *buf;
     945: register n;
     946: {
     947:     register char *p;
     948:
     949:     if (n == 0)
     950:         return OK;
     951:     if (Thisbinary) {
     952:         for (p=buf; --n>=0; )
     953:             putc( *p++, fout);
     954:     }
     955:     else {
     956:         if (Eofseen)
     957:             return OK;
     958:         for (p=buf; --n>=0; ++p ) {
     959:             if ( *p == '\r')
     960:                 continue;
     961:             if (*p == CPMEOF) {
     962:                 Eofseen=TRUE; return OK;
     963:             }
     964:             putc(*p ,fout);
     965:         }
     966:     }
     967:     return OK;
     968: }
     969:
     970: #ifndef vax11c
     971: /*
     972:  *  Send a character to modem.  Small is beautiful.
     973:  */
     974: sendline(c)
     975: {
     976:     char d;
     977:
     978:     d = c;
     979:     if (Verbose>6)
     980:         fprintf(stderr, "Sendline: %x\n", c);
     981:     write(1, &d, 1);
     982: }
     983:
     984: flushmo() {}
     985: #endif
     986:
     987:
     988:
     989:
     990:
     991: /* make string s lower case */
     992: uncaps(s)
     993: register char *s;
     994: {
     995:     for ( ; *s; ++s)
     996:         if (isupper(*s))
     997:             *s = tolower(*s);
     998: }
     999: /*
    1000:  * IsAnyLower returns TRUE if string s has lower case letters.
    1001:  */
    1002: IsAnyLower(s)
    1003: register char *s;
    1004: {
    1005:     for ( ; *s; ++s)
    1006:         if (islower(*s))
    1007:             return TRUE;
    1008:     return FALSE;
    1009: }
    1010:
    1011: /*
    1012:  * substr(string, token) searches for token in string s
    1013:  * returns pointer to token within string if found, NULL otherwise
    1014:  */
    1015: char *
    1016: substr(s, t)
    1017: register char *s,*t;
    1018: {
    1019:     register char *ss,*tt;
    1020:     /* search for first char of token */
    1021:     for (ss=s; *s; s++)
    1022:         if (*s == *t)
    1023:             /* compare token with substring */
    1024:             for (ss=s,tt=t; ;) {
    1025:                 if (*tt == 0)
    1026:                     return s;
    1027:                 if (*ss++ != *tt++)
    1028:                     break;
    1029:             }
    1030:     return NULL;
    1031: }
    1032:
    1033: /*
    1034:  * Log an error
    1035:  */
    1036: /*VARARGS1*/
    1037: zperr(s,p,u)
    1038: char *s, *p, *u;
    1039: {
    1040:     if (Verbose <= 0)
    1041:         return;
    1042:     fprintf(stderr, "Retry %d: ", errors);
    1043:     fprintf(stderr, s, p, u);
    1044:     fprintf(stderr, "\n");
    1045: }
    1046:
    1047: /* send cancel string to get the other end to shut up */
    1048: canit()
    1049: {
    1050:     static char canistr[] = {
    1051:      24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
    1052:     };
    1053:
    1054: #ifdef vax11c
    1055:     raw_wbuf(strlen(canistr), canistr);
    1056:     purgeline();
    1057: #else
    1058:     printf(canistr);
    1059:     Lleft=0;    /* Do read next time ... */
    1060:     fflush(stdout);
    1061: #endif
    1062: }
    1063:
    1064:
    1065: report(sct)
    1066: int sct;
    1067: {
    1068:     if (Verbose>1)
    1069:         fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');
    1070: }
    1071:
    1072: /*
    1073:  * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
    1074:  * If called as [-][dir/../]rzCOMMAND set the pipe flag
    1075:  * If called as rb use YMODEM protocol
    1076:  */
    1077: chkinvok(s)
    1078: char *s;
    1079: {
    1080:     register char *p;
    1081:
    1082:     p = s;
    1083:     while (*p == '-')
    1084:         s = ++p;
    1085:     while (*p)
    1086:         if (*p++ == '/')
    1087:             s = p;
    1088:     if (*s == 'v') {
    1089:         Verbose=1; ++s;
    1090:     }
    1091:     Progname = s;
    1092:     if (s[0]=='r' && s[1]=='z')
    1093:         Batch = TRUE;
    1094:     if (s[0]=='r' && s[1]=='b')
    1095:         Batch = Nozmodem = TRUE;
    1096:     if (s[2] && s[0]=='r' && s[1]=='b')
    1097:         Topipe = 1;
    1098:     if (s[2] && s[0]=='r' && s[1]=='z')
    1099:         Topipe = 1;
    1100: }
    1101:
    1102: /*
    1103:  * Totalitarian Communist pathname processing
    1104:  */
    1105: checkpath(name)
    1106: char *name;
    1107: {
    1108:     if (Restricted) {
    1109:         if (fopen(name, "r") != NULL) {
    1110:             canit();
    1111:             fprintf(stderr, "\r\nrz: %s exists\n", name);
    1112:             bibi(-1);
    1113:         }
    1114:         /* restrict pathnames to current tree or uucppublic */
    1115:         if ( substr(name, "../")
    1116:          || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
    1117:             canit();
    1118:             fprintf(stderr,"\r\nrz:\tSecurity Violation\r\n");
    1119:             bibi(-1);
    1120:         }
    1121:     }
    1122: }
    1123:
    1124: /*
    1125:  * Initialize for Zmodem receive attempt, try to activate Zmodem sender
    1126:  *  Handles ZSINIT frame
    1127:  *  Return ZFILE if Zmodem filename received, -1 on error,
    1128:  *   ZCOMPL if transaction finished,  else 0
    1129:  */
    1130: tryz()
    1131: {
    1132:     register c, n;
    1133:     register cmdzack1flg;
    1134:
    1135:     if (Nozmodem)       /* Check for "rb" program name */
    1136:         return 0;
    1137:
    1138:
    1139:     for (n=Zmodem?15:5; --n>=0; ) {
    1140:         /* Set buffer length (0) and capability flags */
    1141: #ifdef SEGMENTS
    1142:         stohdr(SEGMENTS*1024L);
    1143: #else
    1144:         stohdr(0L);
    1145: #endif
    1146: #ifdef CANBREAK
    1147:         Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
    1148: #else
    1149:         Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
    1150: #endif
    1151:         if (Zctlesc)
    1152:             Txhdr[ZF0] |= TESCCTL;
    1153:         Txhdr[ZF0] |= CANRLE;
    1154:         Txhdr[ZF1] = CANVHDR;
    1155:         /* tryzhdrtype may == ZRINIT */
    1156:         zshhdr(4,tryzhdrtype, Txhdr);
    1157:         if (tryzhdrtype == ZSKIP)   /* Don't skip too far */
    1158:             tryzhdrtype = ZRINIT;   /* CAF 8-21-87 */
    1159: again:
    1160:         switch (zgethdr(Rxhdr, 0)) {
    1161:         case ZRQINIT:
    1162:             if (Rxhdr[ZF3] & 0x80)
    1163:                 Usevhdrs = 1;   /* we can var header */
    1164:             continue;
    1165:         case ZEOF:
    1166:             continue;
    1167:         case TIMEOUT:
    1168:             continue;
    1169:         case ZFILE:
    1170:             zconv = Rxhdr[ZF0];
    1171:             zmanag = Rxhdr[ZF1];
    1172:             ztrans = Rxhdr[ZF2];
    1173:             if (Rxhdr[ZF3] & ZCANVHDR)
    1174:                 Usevhdrs = TRUE;
    1175:             tryzhdrtype = ZRINIT;
    1176:             c = zrdata(secbuf, 1024);
    1177:             mode(3);
    1178:             if (c == GOTCRCW)
    1179:                 return ZFILE;
    1180:             zshhdr(4,ZNAK, Txhdr);
    1181:             goto again;
    1182:         case ZSINIT:
    1183:             Zctlesc = TESCCTL & Rxhdr[ZF0];
    1184:             if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {
    1185:                 stohdr(1L);
    1186:                 zshhdr(4,ZACK, Txhdr);
    1187:                 goto again;
    1188:             }
    1189:             zshhdr(4,ZNAK, Txhdr);
    1190:             goto again;
    1191:         case ZFREECNT:
    1192:             stohdr(getfree());
    1193:             zshhdr(4,ZACK, Txhdr);
    1194:             goto again;
    1195:         case ZCOMMAND:
    1196: #ifdef vax11c
    1197:             return ERROR;
    1198: #else
    1199:             cmdzack1flg = Rxhdr[ZF0];
    1200:             if (zrdata(secbuf, 1024) == GOTCRCW) {
    1201:                 if (cmdzack1flg & ZCACK1)
    1202:                     stohdr(0L);
    1203:                 else
    1204:                     stohdr((long)sys2(secbuf));
    1205:                 purgeline();    /* dump impatient questions */
    1206:                 do {
    1207:                     zshhdr(4,ZCOMPL, Txhdr);
    1208:                 }
    1209:                 while (++errors<20 && zgethdr(Rxhdr,1) != ZFIN);
    1210:                 ackbibi();
    1211:                 if (cmdzack1flg & ZCACK1)
    1212:                     exec2(secbuf);
    1213:                 return ZCOMPL;
    1214:             }
    1215:             zshhdr(4,ZNAK, Txhdr); goto again;
    1216: #endif
    1217:         case ZCOMPL:
    1218:             goto again;
    1219:         default:
    1220:             continue;
    1221:         case ZFIN:
    1222:             ackbibi(); return ZCOMPL;
    1223:         case ZCAN:
    1224:             return ERROR;
    1225:         }
    1226:     }
    1227:     return 0;
    1228: }
    1229:
    1230: /*
    1231:  * Receive 1 or more files with ZMODEM protocol
    1232:  */
    1233: rzfiles()
    1234: {
    1235:     register c;
    1236:
    1237:     for (;;) {
    1238:         switch (c = rzfile()) {
    1239:         case ZEOF:
    1240:         case ZSKIP:
    1241:             switch (tryz()) {
    1242:             case ZCOMPL:
    1243:                 return OK;
    1244:             default:
    1245:                 return ERROR;
    1246:             case ZFILE:
    1247:                 break;
    1248:             }
    1249:             continue;
    1250:         default:
    1251:             return c;
    1252:         case ERROR:
    1253:             return ERROR;
    1254:         }
    1255:     }
    1256: }
    1257:
    1258: /*
    1259:  * Receive a file with ZMODEM protocol
    1260:  *  Assumes file name frame is in secbuf
    1261:  */
    1262: rzfile()
    1263: {
    1264:     register c, n;
    1265:     long rxbytes;
    1266:
    1267:     Eofseen=FALSE;
    1268:     if (procheader(secbuf) == ERROR) {
    1269:         return (tryzhdrtype = ZSKIP);
    1270:     }
    1271:
    1272:     n = 20; rxbytes = 0l;
    1273:
    1274:     for (;;) {
    1275: #ifdef SEGMENTS
    1276:         chinseg = 0;
    1277: #endif
    1278:         stohdr(rxbytes);
    1279:         zshhdr(4,ZRPOS, Txhdr);
    1280: nxthdr:
    1281:         switch (c = zgethdr(Rxhdr, 0)) {
    1282:         default:
    1283:             vfile("rzfile: zgethdr returned %d", c);
    1284:             return ERROR;
    1285:         case ZNAK:
    1286:         case TIMEOUT:
    1287: #ifdef SEGMENTS
    1288:             putsec(secbuf, chinseg);
    1289:             chinseg = 0;
    1290: #endif
    1291:             if ( --n < 0) {
    1292:                 vfile("rzfile: zgethdr returned %d", c);
    1293:                 return ERROR;
    1294:             }
    1295:         case ZFILE:
    1296:             zrdata(secbuf, 1024);
    1297:             continue;
    1298:         case ZEOF:
    1299: #ifdef SEGMENTS
    1300:             putsec(secbuf, chinseg);
    1301:             chinseg = 0;
    1302: #endif
    1303:             if (rclhdr(Rxhdr) != rxbytes) {
    1304:                 /*
    1305: 				 * Ignore eof if it's at wrong place - force
    1306: 				 *  a timeout because the eof might have gone
    1307: 				 *  out before we sent our zrpos.
    1308: 				 */
    1309:                 errors = 0;  goto nxthdr;
    1310:             }
    1311:             if (closeit()) {
    1312:                 tryzhdrtype = ZFERR;
    1313:                 vfile("rzfile: closeit returned <> 0");
    1314:                 return ERROR;
    1315:             }
    1316:             vfile("rzfile: normal EOF");
    1317:             return c;
    1318:         case ERROR: /* Too much garbage in header search error */
    1319: #ifdef SEGMENTS
    1320:             putsec(secbuf, chinseg);
    1321:             chinseg = 0;
    1322: #endif
    1323:             if ( --n < 0) {
    1324:                 vfile("rzfile: zgethdr returned %d", c);
    1325:                 return ERROR;
    1326:             }
    1327:             zmputs(Attn);
    1328:             continue;
    1329:         case ZSKIP:
    1330: #ifdef SEGMENTS
    1331:             putsec(secbuf, chinseg);
    1332:             chinseg = 0;
    1333: #endif
    1334:             Modtime = 1;
    1335:             closeit();
    1336:             vfile("rzfile: Sender SKIPPED file");
    1337:             return c;
    1338:         case ZDATA:
    1339:             if (rclhdr(Rxhdr) != rxbytes) {
    1340:                 if ( --n < 0) {
    1341:                     return ERROR;
    1342:                 }
    1343: #ifdef SEGMENTS
    1344:                 putsec(secbuf, chinseg);
    1345:                 chinseg = 0;
    1346: #endif
    1347:                 zmputs(Attn);  continue;
    1348:             }
    1349: moredata:
    1350:             if (Verbose>1)
    1351:                 fprintf(stderr, "\r%7ld ZMODEM%s    ",
    1352:                   rxbytes, Crc32r?" CRC-32":"");
    1353: #ifdef SEGMENTS
    1354:             if (chinseg >= (1024 * SEGMENTS)) {
    1355:                 putsec(secbuf, chinseg);
    1356:                 chinseg = 0;
    1357:             }
    1358:             switch (c = zrdata(secbuf+chinseg, 1024))
    1359: #else
    1360:             switch (c = zrdata(secbuf, 1024))
    1361: #endif
    1362:             {
    1363:             case ZCAN:
    1364: #ifdef SEGMENTS
    1365:                 putsec(secbuf, chinseg);
    1366:                 chinseg = 0;
    1367: #endif
    1368:                 vfile("rzfile: zgethdr returned %d", c);
    1369:                 return ERROR;
    1370:             case ERROR: /* CRC error */
    1371: #ifdef SEGMENTS
    1372:                 putsec(secbuf, chinseg);
    1373:                 chinseg = 0;
    1374: #endif
    1375:                 if ( --n < 0) {
    1376:                     vfile("rzfile: zgethdr returned %d", c);
    1377:                     return ERROR;
    1378:                 }
    1379:                 zmputs(Attn);
    1380:                 continue;
    1381:             case TIMEOUT:
    1382: #ifdef SEGMENTS
    1383:                 putsec(secbuf, chinseg);
    1384:                 chinseg = 0;
    1385: #endif
    1386:                 if ( --n < 0) {
    1387:                     vfile("rzfile: zgethdr returned %d", c);
    1388:                     return ERROR;
    1389:                 }
    1390:                 continue;
    1391:             case GOTCRCW:
    1392:                 n = 20;
    1393: #ifdef SEGMENTS
    1394:                 chinseg += Rxcount;
    1395:                 putsec(secbuf, chinseg);
    1396:                 chinseg = 0;
    1397: #else
    1398:                 putsec(secbuf, Rxcount);
    1399: #endif
    1400:                 rxbytes += Rxcount;
    1401:                 stohdr(rxbytes);
    1402:                 zshhdr(4,ZACK, Txhdr);
    1403:                 sendline(XON);
    1404:                 goto nxthdr;
    1405:             case GOTCRCQ:
    1406:                 n = 20;
    1407: #ifdef SEGMENTS
    1408:                 chinseg += Rxcount;
    1409: #else
    1410:                 putsec(secbuf, Rxcount);
    1411: #endif
    1412:                 rxbytes += Rxcount;
    1413:                 stohdr(rxbytes);
    1414:                 zshhdr(4,ZACK, Txhdr);
    1415:                 goto moredata;
    1416:             case GOTCRCG:
    1417:                 n = 20;
    1418: #ifdef SEGMENTS
    1419:                 chinseg += Rxcount;
    1420: #else
    1421:                 putsec(secbuf, Rxcount);
    1422: #endif
    1423:                 rxbytes += Rxcount;
    1424:                 goto moredata;
    1425:             case GOTCRCE:
    1426:                 n = 20;
    1427: #ifdef SEGMENTS
    1428:                 chinseg += Rxcount;
    1429: #else
    1430:                 putsec(secbuf, Rxcount);
    1431: #endif
    1432:                 rxbytes += Rxcount;
    1433:                 goto nxthdr;
    1434:             }
    1435:         }
    1436:     }
    1437: }
    1438:
    1439: /*
    1440:  * Send a string to the modem, processing for \336 (sleep 1 sec)
    1441:  *   and \335 (break signal)
    1442:  */
    1443: zmputs(s)
    1444: char *s;
    1445: {
    1446:     register c;
    1447:
    1448:     while (*s) {
    1449:         switch (c = *s++) {
    1450:         case '\336':
    1451:             sleep(1); continue;
    1452:         case '\335':
    1453:             sendbrk(); continue;
    1454:         default:
    1455:             sendline(c);
    1456:         }
    1457:     }
    1458: }
    1459:
    1460: /*
    1461:  * Close the receive dataset, return OK or ERROR
    1462:  */
    1463: closeit()
    1464: {
    1465:     time_t time();
    1466:
    1467: #ifndef vax11c
    1468:     if (Topipe) {
    1469:         if (pclose(fout)) {
    1470:             return ERROR;
    1471:         }
    1472:         return OK;
    1473:     }
    1474: #endif
    1475:     if (fclose(fout)==ERROR) {
    1476:         fprintf(stderr, "file close ERROR\n");
    1477:         return ERROR;
    1478:     }
    1479: #ifndef vax11c
    1480:     if (Modtime) {
    1481:         timep[0] = time(NULL);
    1482:         timep[1] = Modtime;
    1483:         utime(Pathname, timep);
    1484:     }
    1485: #endif
    1486:     if ((Filemode&S_IFMT) == S_IFREG)
    1487:         chmod(Pathname, (07777 & Filemode));
    1488:     return OK;
    1489: }
    1490:
    1491: /*
    1492:  * Ack a ZFIN packet, let byegones be byegones
    1493:  */
    1494: ackbibi()
    1495: {
    1496:     register n;
    1497:
    1498:     vfile("ackbibi:");
    1499:     Readnum = 1;
    1500:     stohdr(0L);
    1501:     for (n=3; --n>=0; ) {
    1502:         purgeline();
    1503:         zshhdr(4,ZFIN, Txhdr);
    1504:         switch (readline(100)) {
    1505:         case 'O':
    1506:             readline(1);    /* Discard 2nd 'O' */
    1507:             vfile("ackbibi complete");
    1508:             return;
    1509:         case RCDO:
    1510:             return;
    1511:         case TIMEOUT:
    1512:         default:
    1513:             break;
    1514:         }
    1515:     }
    1516: }
    1517:
    1518:
    1519:
    1520: /*
    1521:  * Local console output simulation
    1522:  */
    1523: bttyout(c)
    1524: {
    1525:     if (Verbose || Fromcu)
    1526:         putc(c, stderr);
    1527: }
    1528:
    1529: #ifndef vax11c
    1530: /*
    1531:  * Strip leading ! if present, do shell escape.
    1532:  */
    1533: sys2(s)
    1534: register char *s;
    1535: {
    1536:     if (*s == '!')
    1537:         ++s;
    1538:     return system(s);
    1539: }
    1540: /*
    1541:  * Strip leading ! if present, do exec.
    1542:  */
    1543: exec2(s)
    1544: register char *s;
    1545: {
    1546:     if (*s == '!')
    1547:         ++s;
    1548:     mode(0);
    1549:     execl("/bin/sh", "sh", "-c", s);
    1550: }
    1551: #endif
    1552: /* End of rz.c */

#### Defined functions

IsAnyLower defined in line 1002; used 1 times

- in line 793

ackbibi defined in line 1494; used 2 times

- in line 1210, 1222

alrm defined in line 247; used 1 times

- in line 699

bibi defined in line 253; used 7 times

- in line 359-365(4), 1112, 1119
- in /usr/src/local/zmodem/rbsb.c line 270

bttyout defined in line 1523; used 2 times

- in /usr/src/local/zmodem/zm.c line 473-475(2)

canit defined in line 1048; used 7 times

- in line 257, 368-372(2), 459, 660, 1110, 1117

checkpath defined in line 1105; used 2 times

- in line 450, 812

chkinvok defined in line 1077; used 2 times

- in line 279-281(2)

closeit defined in line 1463; used 3 times

- in line 546, 1311, 1335

exec2 defined in line 1543; used 1 times

- in line 1212

flushmo defined in line 984; never used
getfree defined in line 182; used 1 times

- in line 1192

main defined in line 263; never used
make_dirs defined in line 848; used 1 times

- in line 826

mkdir defined in line 892; used 1 times

- in line 867

procheader defined in line 734; used 3 times

- in line 441, 450, 1268

purgeline defined in line 719; used 4 times

- in line 491, 1056, 1205, 1502

putsec defined in line 943; used 15 times

- in line 535, 1288, 1300, 1320, 1331, 1344, 1355, 1365, 1372, 1383, 1395-1398(2), 1410, 1421, 1430

readline defined in line 672; used 12 times

- in line 489, 503, 582, 588-601(5), 623, 649, 1504-1506(2)

report defined in line 1065; used 1 times

- in line 531

rzfile defined in line 1262; used 1 times

- in line 1238

rzfiles defined in line 1233; used 1 times

- in line 432

sendline defined in line 974; used 10 times

- in line 239, 496-501(2), 508, 528, 548, 652-655(2), 1403, 1455

substr defined in line 1015; used 4 times

- in line 175, 274(2), 1115

sys2 defined in line 1533; used 1 times

- in line 1204

tryz defined in line 1130; used 2 times

- in line 427, 1241

uncaps defined in line 992; used 1 times

- in line 795

usage defined in line 379; used 6 times

- in line 311-319(3), 330, 342-344(2)

vfile defined in line 402; used 29 times

- in line 357, 868, 1283, 1292, 1313-1316(2), 1324, 1336, 1368, 1376, 1387, 1498, 1507
- in /usr/src/local/zmodem/genie.c line 59
- in /usr/src/local/zmodem/rbsb.c line 175
- in /usr/src/local/zmodem/vrzsz.c line 46
- in /usr/src/local/zmodem/zm.c line 122, 192, 232, 321, 383, 573-576(2), 632, 641, 649, 720, 776
- in /usr/src/local/zmodem/zmr.c line 138

wcgetsec defined in line 571; used 2 times

- in line 498, 530

wcreceive defined in line 418; used 1 times

- in line 366

wcrx defined in line 517; used 2 times

- in line 443, 454

wcrxpn defined in line 483; used 1 times

- in line 437

zmputs defined in line 1443; used 4 times

- in line 256, 1327, 1347, 1379

zperr defined in line 1037; used 28 times

- in line 500, 542, 555, 605, 616-619(2), 631, 642-645(2)
- in /usr/src/local/zmodem/zm.c line 316, 326-329(2), 341, 378, 388-391(2), 400, 406, 568, 610, 653, 690, 863
- in /usr/src/local/zmodem/zmr.c line 133, 143-149(3), 182

#### Defined variables

Batch defined in line 207; used 4 times

- in line 343, 423, 1093-1095(2)

Baudrate defined in line 166; never used
Blklen defined in line 217; used 5 times

- in line 534(2), 583-591(3)

Bytesleft defined in line 201; used 8 times

- in line 448, 534-538(4), 762-766(2), 773

Crcflg defined in line 188; used 6 times

- in line 298, 424, 496, 525, 599, 652

Effbaud defined in line 167; never used
Eofseen defined in line 190; used 5 times

- in line 495, 524, 956, 962, 1267

Filemode defined in line 203; used 8 times

- in line 448, 762-773(4), 794, 1486-1487(2)

Firstsec defined in line 189; used 6 times

- in line 495, 524, 607-612(2), 639, 651

Lastrx defined in line 187; used 4 times

- in line 580, 630-634(2), 648

Lleft defined in line 228; used 15 times

- in line 497-502(2), 529, 549, 626, 653-656(2), 678, 694, 700-707(4), 721, 1059

Lzmanag defined in line 230; used 4 times

- in line 292, 306, 742-743(2)

MakeLCPathname defined in line 209; used 2 times

- in line 324, 793

Modtime defined in line 202; used 8 times

- in line 448, 465, 762-766(2), 773, 1334, 1480-1482(2)

Nflag defined in line 212; used 2 times

- in line 301, 813

Nozmodem defined in line 165; used 3 times

- in line 426, 1095, 1135

Pathname defined in line 204; used 12 times

- in line 450-452(4), 470-471(2), 798-807(4), 1483-1487(2)

Progname defined in line 205; used 6 times

- in line 351, 357, 394, 426, 798, 1091

Quiet defined in line 211; used 3 times

- in line 308, 353, 425

Readnum defined in line 197; used 3 times

- in line 689, 700, 1499

Restricted defined in line 192; used 3 times

- in line 275, 469, 1108

Rxascii defined in line 215; used 2 times

- in line 294, 741

Rxbinary defined in line 214; used 3 times

- in line 296, 741, 748

Rxclob defined in line 213; used 2 times

- in line 328, 757

Thisbinary defined in line 216; used 7 times

- in line 741, 749-751(2), 769, 801, 810, 951

Topipe defined in line 208; used 6 times

- in line 461, 797, 820, 1097-1099(2), 1468

Verbose defined in line 210; used 20 times

- in line 308, 326, 345, 354-355(2), 405, 679, 687, 695, 702, 708, 771, 799, 808, 979, 1040, 1068, 1089, 1350, 1525

Zctlesc defined in line 234; used 3 times

- in line 304, 1151, 1183

Zmodem defined in line 164; used 4 times

- in line 255, 371, 793, 1139

Zrwindow defined in line 235; used 1 times

- in line 321

chinseg defined in line 220; used 27 times

- in line 1276, 1288-1289(2), 1300-1301(2), 1320-1321(2), 1331-1332(2), 1344-1345(2), 1354-1358(4), 1365-1366(2), 1372-1373(2), 1383-1384(2), 1394-1396(3), 1408, 1419, 1428

errors defined in line 191; used 6 times

- in line 580(3), 1042, 1209, 1309

linbuf defined in line 227; used 1 times

- in line 700

rbmsg defined in line 415; used 1 times

- in line 426

secbuf defined in line 223; used 27 times

- in line 437-441(3), 530-535(2), 1176, 1200-1204(2), 1212, 1268, 1288, 1296-1300(2), 1320, 1331, 1344, 1355-1365(4), 1372, 1383, 1395-1398(2), 1410, 1421, 1430

timep defined in line 229; used 3 times

- in line 1481-1483(3)

tohere defined in line 237; used 2 times

- in line 249, 690

tryzhdrtype defined in line 245; used 6 times

- in line 1156-1158(3), 1175, 1269, 1312

zconv defined in line 231; used 3 times

- in line 748-750(2), 1170

zmanag defined in line 232; used 4 times

- in line 743, 752-757(2), 1171

ztrans defined in line 233; used 1 times

- in line 1172

#### Defined macros

ACK defined in line 151; used 5 times

- in line 501, 508, 539-548(3)

BUFREAD defined in line 106; never used
CAN defined in line 145; used 3 times

- in line 629-634(3)

CPMEOF defined in line 153; used 1 times

- in line 961

DEFBYTL defined in line 200; used 2 times

- in line 448, 762

ENQ defined in line 144; never used
EOT defined in line 150; used 2 times

- in line 623-626(2)

ERROR defined in line 132; used 39 times

- in line 366, 430, 437-443(3), 453-454(2), 462, 474, 506, 535-536(2), 547-556(4), 632, 661, 758, 779, 804, 818, 832, 1197, 1224, 1245, 1253, 1268, 1284, 1293, 1314, 1325, 1341, 1369, 1377, 1388, 1470-1477(3)

ERRORMAX defined in line 158; never used
FALSE defined in line 130; used 10 times

- in line 213-215(3), 324, 495, 524, 607-612(2), 1008, 1267

GCOUNT defined in line 157; never used
HOWMANY defined in line 140; used 3 times

- in line 139, 197, 227

LOGFILE defined in line 119; used 2 times

- in line 346-347(2)

NAK defined in line 152; used 4 times

- in line 496, 525, 652-655(2)

OK defined in line 129; used 15 times

- in line 429, 440, 457, 509, 550, 780, 820, 834, 950, 957-967(3), 1243, 1472, 1488

OS defined in line 105; used 2 times

- in line 357, 394

PATHLEN defined in line 161; used 1 times

- in line 204

PROGNAME defined in line 111; used 2 times

- in line 110, 279

PUBDIR defined in line 2; used 2 times

- in line 1116(2)

RCDO defined in line 156; never used
RETRYMAX defined in line 159; used 1 times

- in line 580

SOH defined in line 148; used 1 times

- in line 585

SS_NORMAL defined in line 118; used 2 times

- in line 375, 396

STX defined in line 149; used 1 times

- in line 582

TERM_COREDUMP defined in line 887; never used
TERM_SIGNAL defined in line 886; used 1 times

- in line 928

TERM_VALUE defined in line 888; used 1 times

- in line 928

TIMEOUT defined in line 155; used 5 times

- in line 623, 638, 649, 697, 706

TRUE defined in line 131; used 16 times

- in line 209, 275, 294-301(4), 308, 328, 495, 524, 751, 962, 1007, 1093-1095(2), 1174

UNIXFILE defined in line 162; used 2 times

- in line 768, 794

VERSION defined in line 1; used 2 times

- in line 357, 394

WANTCRC defined in line 154; used 3 times

- in line 496, 525, 652

WCEOT defined in line 160; used 4 times

- in line 499, 545, 624-627(2)

XOFF defined in line 146; never used
XON defined in line 147; used 1 times

- in line 1403

xsendline defined in line 239; never used

Last modified: 1992-06-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 6657 |