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

##### Functions

    garbitch          X
    noxrd7            X
    rclhdr            X
    stohdr            X
    zdlread           X
    zgeth1            X
    zgethdr           X
    zgethex           X
    zputhex           X
    zrbhd32           X
    zrbhdr            X
    zrdat32           X
    zrdata            X
    zrhhdr            X
    zsbh32            X
    zsbhdr            X
    zsda32            X
    zsdata            X
    zsendline         X
    zshhdr            X

##### Variables

    Altcan            X
    Attn              X
    Crc32r            X
    Crc32t            X
    Rxcount           X
    Rxframeind        X
    Rxhdr             X
    Rxhlen            X
    Rxpos             X
    Rxtimeout         X
    Rxtype            X
    Txfcs32           X
    Txhdr             X
    Txpos             X
    Usevhdrs          X
    Znulls            X

##### Macros

    FRTYPES           X
    FTOFFSET          X
    UNSL              X

       1: /*
       2:  *   Z M . C
       3:  *    ZMODEM protocol primitives
       4:  *    05-24-89  Chuck Forsberg Omen Technology Inc
       5:  *
       6:  * Entry point Functions:
       7:  *	zsbhdr(type, hdr) send binary header
       8:  *	zshhdr(type, hdr) send hex header
       9:  *	zgethdr(hdr, eflag) receive header - binary or hex
      10:  *	zsdata(buf, len, frameend) send data
      11:  *	zrdata(buf, len) receive data
      12:  *	stohdr(pos) store position data in Txhdr
      13:  *	long rclhdr(hdr) recover position offset from header
      14:  *
      15:  *
      16:  *	This version implements numerous enhancements including ZMODEM
      17:  *	Run Length Encoding and variable length headers.  These
      18:  *	features were not funded by the original Telenet development
      19:  *	contract.
      20:  *
      21:  * This software may be freely used for non commercial and
      22:  * educational (didactic only) purposes.  This software may also
      23:  * be freely used to support file transfer operations to or from
      24:  * licensed Omen Technology products.  Any programs which use
      25:  * part or all of this software must be provided in source form
      26:  * with this notice intact except by written permission from Omen
      27:  * Technology Incorporated.
      28:  *
      29:  * Use of this software for commercial or administrative purposes
      30:  * except when exclusively limited to interfacing Omen Technology
      31:  * products requires a per port license payment of $20.00 US per
      32:  * port (less in quantity).  Use of this code by inclusion,
      33:  * decompilation, reverse engineering or any other means
      34:  * constitutes agreement to these conditions and acceptance of
      35:  * liability to license the materials and payment of reasonable
      36:  * legal costs necessary to enforce this license agreement.
      37:  *
      38:  *
      39:  *		Omen Technology Inc		FAX: 503-621-3745
      40:  *		Post Office Box 4681
      41:  *		Portland OR 97208
      42:  *
      43:  *	This code is made available in the hope it will be useful,
      44:  *	BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
      45:  *	DAMAGES OF ANY KIND.
      46:  *
      47:  */
      48:
      49: #ifndef CANFDX
      50: #include "zmodem.h"
      51: int Rxtimeout = 100;        /* Tenths of seconds to wait for something */
      52: #endif
      53:
      54: #ifndef UNSL
      55: #define UNSL
      56: #endif
      57:
      58:
      59: /* Globals used by ZMODEM functions */
      60: int Rxframeind;     /* ZBIN ZBIN32, or ZHEX type of frame */
      61: int Rxtype;     /* Type of header received */
      62: int Rxhlen;     /* Length of header received */
      63: int Rxcount;        /* Count of data bytes received */
      64: char Rxhdr[ZMAXHLEN];   /* Received header */
      65: char Txhdr[ZMAXHLEN];   /* Transmitted header */
      66: long Rxpos;     /* Received file position */
      67: long Txpos;     /* Transmitted file position */
      68: int Txfcs32;        /* TURE means send binary frames with 32 bit FCS */
      69: int Crc32t;     /* Controls 32 bit CRC being sent */
      70:             /* 1 == CRC32,  2 == CRC32 + RLE */
      71: int Crc32r;     /* Indicates/controls 32 bit CRC being received */
      72:             /* 0 == CRC16,  1 == CRC32,  2 == CRC32 + RLE */
      73: int Usevhdrs;       /* Use variable length headers */
      74: int Znulls;     /* Number of nulls to send at beginning of ZDATA hdr */
      75: char Attn[ZATTNLEN+1];  /* Attention string rx sends to tx on err */
      76: char *Altcan;       /* Alternate canit string */
      77:
      78: static lastsent;    /* Last char we sent */
      79: static Not8bit;     /* Seven bits seen on header */
      80:
      81: static char *frametypes[] = {
      82:     "No Response to Error Correction Request",  /* -4 */
      83:     "No Carrier Detect",        /* -3 */
      84:     "TIMEOUT",      /* -2 */
      85:     "ERROR",        /* -1 */
      86: #define FTOFFSET 4
      87:     "ZRQINIT",
      88:     "ZRINIT",
      89:     "ZSINIT",
      90:     "ZACK",
      91:     "ZFILE",
      92:     "ZSKIP",
      93:     "ZNAK",
      94:     "ZABORT",
      95:     "ZFIN",
      96:     "ZRPOS",
      97:     "ZDATA",
      98:     "ZEOF",
      99:     "ZFERR",
     100:     "ZCRC",
     101:     "ZCHALLENGE",
     102:     "ZCOMPL",
     103:     "ZCAN",
     104:     "ZFREECNT",
     105:     "ZCOMMAND",
     106:     "ZSTDERR",
     107:     "xxxxx"
     108: #define FRTYPES 22  /* Total number of frame types in this array */
     109:             /*  not including psuedo negative entries */
     110: };
     111:
     112: static char badcrc[] = "Bad CRC";
     113:
     114: /* Send ZMODEM binary header hdr of type type */
     115: zsbhdr(len, type, hdr)
     116: register char *hdr;
     117: {
     118:     register int n;
     119:     register unsigned short crc;
     120:
     121: #ifndef DSZ
     122:     vfile("zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len,
     123:       frametypes[type+FTOFFSET], rclhdr(hdr));
     124: #endif
     125:     if (type == ZDATA)
     126:         for (n = Znulls; --n >=0; )
     127:             xsendline(0);
     128:
     129:     xsendline(ZPAD); xsendline(ZDLE);
     130:
     131:     switch (Crc32t=Txfcs32) {
     132:     case 2:
     133:         zsbh32(len, hdr, type, Usevhdrs?ZVBINR32:ZBINR32);
     134:         flushmo();  break;
     135:     case 1:
     136:         zsbh32(len, hdr, type, Usevhdrs?ZVBIN32:ZBIN32);  break;
     137:     default:
     138:         if (Usevhdrs) {
     139:             xsendline(ZVBIN);
     140:             zsendline(len);
     141:         }
     142:         else
     143:             xsendline(ZBIN);
     144:         zsendline(type);
     145:         crc = updcrc(type, 0);
     146:
     147:         for (n=len; --n >= 0; ++hdr) {
     148:             zsendline(*hdr);
     149:             crc = updcrc((0377& *hdr), crc);
     150:         }
     151:         crc = updcrc(0,updcrc(0,crc));
     152:         zsendline(crc>>8);
     153:         zsendline(crc);
     154:     }
     155:     if (type != ZDATA)
     156:         flushmo();
     157: }
     158:
     159:
     160: /* Send ZMODEM binary header hdr of type type */
     161: zsbh32(len, hdr, type, flavour)
     162: register char *hdr;
     163: {
     164:     register int n;
     165:     register UNSL long crc;
     166:
     167:     xsendline(flavour);
     168:     if (Usevhdrs)
     169:         zsendline(len);
     170:     zsendline(type);
     171:     crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
     172:
     173:     for (n=len; --n >= 0; ++hdr) {
     174:         crc = UPDC32((0377 & *hdr), crc);
     175:         zsendline(*hdr);
     176:     }
     177:     crc = ~crc;
     178:     for (n=4; --n >= 0;) {
     179:         zsendline((int)crc);
     180:         crc >>= 8;
     181:     }
     182: }
     183:
     184: /* Send ZMODEM HEX header hdr of type type */
     185: zshhdr(len, type, hdr)
     186: register char *hdr;
     187: {
     188:     register int n;
     189:     register unsigned short crc;
     190:
     191: #ifndef DSZ
     192:     vfile("zshhdr: %c %d %s %lx", Usevhdrs?'v':'f', len,
     193:       frametypes[type+FTOFFSET], rclhdr(hdr));
     194: #endif
     195:     sendline(ZPAD); sendline(ZPAD); sendline(ZDLE);
     196:     if (Usevhdrs) {
     197:         sendline(ZVHEX);
     198:         zputhex(len);
     199:     }
     200:     else
     201:         sendline(ZHEX);
     202:     zputhex(type);
     203:     Crc32t = 0;
     204:
     205:     crc = updcrc(type, 0);
     206:     for (n=len; --n >= 0; ++hdr) {
     207:         zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
     208:     }
     209:     crc = updcrc(0,updcrc(0,crc));
     210:     zputhex(crc>>8); zputhex(crc);
     211:
     212:     /* Make it printable on remote machine */
     213:     sendline(015); sendline(0212);
     214:     /*
     215: 	 * Uncork the remote in case a fake XOFF has stopped data flow
     216: 	 */
     217:     if (type != ZFIN && type != ZACK)
     218:         sendline(021);
     219:     flushmo();
     220: }
     221:
     222: /*
     223:  * Send binary array buf of length length, with ending ZDLE sequence frameend
     224:  */
     225: static char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
     226: zsdata(buf, length, frameend)
     227: register char *buf;
     228: {
     229:     register unsigned short crc;
     230:
     231: #ifndef DSZ
     232:     vfile("zsdata: %d %s", length, Zendnames[frameend-ZCRCE&3]);
     233: #endif
     234:     switch (Crc32t) {
     235:     case 1:
     236:         zsda32(buf, length, frameend);  break;
     237:     case 2:
     238:         zsdar32(buf, length, frameend);  break;
     239:     default:
     240:         crc = 0;
     241:         for (;--length >= 0; ++buf) {
     242:             zsendline(*buf); crc = updcrc((0377 & *buf), crc);
     243:         }
     244:         xsendline(ZDLE); xsendline(frameend);
     245:         crc = updcrc(frameend, crc);
     246:
     247:         crc = updcrc(0,updcrc(0,crc));
     248:         zsendline(crc>>8); zsendline(crc);
     249:     }
     250:     if (frameend == ZCRCW) {
     251:         xsendline(XON);  flushmo();
     252:     }
     253: }
     254:
     255: zsda32(buf, length, frameend)
     256: register char *buf;
     257: {
     258:     register int c;
     259:     register UNSL long crc;
     260:
     261:     crc = 0xFFFFFFFFL;
     262:     for (;--length >= 0; ++buf) {
     263:         c = *buf & 0377;
     264:         if (c & 0140)
     265:             xsendline(lastsent = c);
     266:         else
     267:             zsendline(c);
     268:         crc = UPDC32(c, crc);
     269:     }
     270:     xsendline(ZDLE); xsendline(frameend);
     271:     crc = UPDC32(frameend, crc);
     272:
     273:     crc = ~crc;
     274:     for (c=4; --c >= 0;) {
     275:         zsendline((int)crc);  crc >>= 8;
     276:     }
     277: }
     278:
     279: /*
     280:  * Receive array buf of max length with ending ZDLE sequence
     281:  *  and CRC.  Returns the ending character or error code.
     282:  *  NB: On errors may store length+1 bytes!
     283:  */
     284: zrdata(buf, length)
     285: register char *buf;
     286: {
     287:     register int c;
     288:     register unsigned short crc;
     289:     register char *end;
     290:     register int d;
     291:
     292:     switch (Crc32r) {
     293:     case 1:
     294:         return zrdat32(buf, length);
     295:     case 2:
     296:         return zrdatr32(buf, length);
     297:     }
     298:
     299:     crc = Rxcount = 0;  end = buf + length;
     300:     while (buf <= end) {
     301:         if ((c = zdlread()) & ~0377) {
     302: crcfoo:
     303:             switch (c) {
     304:             case GOTCRCE:
     305:             case GOTCRCG:
     306:             case GOTCRCQ:
     307:             case GOTCRCW:
     308:                 crc = updcrc((d=c)&0377, crc);
     309:                 if ((c = zdlread()) & ~0377)
     310:                     goto crcfoo;
     311:                 crc = updcrc(c, crc);
     312:                 if ((c = zdlread()) & ~0377)
     313:                     goto crcfoo;
     314:                 crc = updcrc(c, crc);
     315:                 if (crc & 0xFFFF) {
     316:                     zperr(badcrc);
     317:                     return ERROR;
     318:                 }
     319:                 Rxcount = length - (end - buf);
     320: #ifndef DSZ
     321:                 vfile("zrdata: %d  %s", Rxcount,
     322:                  Zendnames[d-GOTCRCE&3]);
     323: #endif
     324:                 return d;
     325:             case GOTCAN:
     326:                 zperr("Sender Canceled");
     327:                 return ZCAN;
     328:             case TIMEOUT:
     329:                 zperr("TIMEOUT");
     330:                 return c;
     331:             default:
     332:                 garbitch(); return c;
     333:             }
     334:         }
     335:         *buf++ = c;
     336:         crc = updcrc(c, crc);
     337:     }
     338: #ifdef DSZ
     339:     garbitch();
     340: #else
     341:     zperr("Data subpacket too long");
     342: #endif
     343:     return ERROR;
     344: }
     345:
     346: zrdat32(buf, length)
     347: register char *buf;
     348: {
     349:     register int c;
     350:     register UNSL long crc;
     351:     register char *end;
     352:     register int d;
     353:
     354:     crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
     355:     while (buf <= end) {
     356:         if ((c = zdlread()) & ~0377) {
     357: crcfoo:
     358:             switch (c) {
     359:             case GOTCRCE:
     360:             case GOTCRCG:
     361:             case GOTCRCQ:
     362:             case GOTCRCW:
     363:                 d = c;  c &= 0377;
     364:                 crc = UPDC32(c, crc);
     365:                 if ((c = zdlread()) & ~0377)
     366:                     goto crcfoo;
     367:                 crc = UPDC32(c, crc);
     368:                 if ((c = zdlread()) & ~0377)
     369:                     goto crcfoo;
     370:                 crc = UPDC32(c, crc);
     371:                 if ((c = zdlread()) & ~0377)
     372:                     goto crcfoo;
     373:                 crc = UPDC32(c, crc);
     374:                 if ((c = zdlread()) & ~0377)
     375:                     goto crcfoo;
     376:                 crc = UPDC32(c, crc);
     377:                 if (crc != 0xDEBB20E3) {
     378:                     zperr(badcrc);
     379:                     return ERROR;
     380:                 }
     381:                 Rxcount = length - (end - buf);
     382: #ifndef DSZ
     383:                 vfile("zrdat32: %d %s", Rxcount,
     384:                  Zendnames[d-GOTCRCE&3]);
     385: #endif
     386:                 return d;
     387:             case GOTCAN:
     388:                 zperr("Sender Canceled");
     389:                 return ZCAN;
     390:             case TIMEOUT:
     391:                 zperr("TIMEOUT");
     392:                 return c;
     393:             default:
     394:                 garbitch(); return c;
     395:             }
     396:         }
     397:         *buf++ = c;
     398:         crc = UPDC32(c, crc);
     399:     }
     400:     zperr("Data subpacket too long");
     401:     return ERROR;
     402: }
     403:
     404: garbitch()
     405: {
     406:     zperr("Garbled data subpacket");
     407: }
     408:
     409: /*
     410:  * Read a ZMODEM header to hdr, either binary or hex.
     411:  *  eflag controls local display of non zmodem characters:
     412:  *	0:  no display
     413:  *	1:  display printing characters only
     414:  *	2:  display all non ZMODEM characters
     415:  *
     416:  *   Set Rxhlen to size of header (default 4) (valid iff good hdr)
     417:  *  On success, set Zmodem to 1, set Rxpos and return type of header.
     418:  *   Otherwise return negative on error.
     419:  *   Return ERROR instantly if ZCRCW sequence, for fast error recovery.
     420:  */
     421: zgethdr(hdr, eflag)
     422: char *hdr;
     423: {
     424:     register int c, n, cancount;
     425:
     426:     n = Zrwindow + Effbaud;     /* Max bytes before start of frame */
     427:     Rxframeind = Rxtype = 0;
     428:
     429: startover:
     430:     cancount = 5;
     431: again:
     432:     /* Return immediate ERROR if ZCRCW sequence seen */
     433:     switch (c = readline(Rxtimeout)) {
     434:     case 021: case 0221:
     435:         goto again;
     436:     case RCDO:
     437:     case TIMEOUT:
     438:         goto fifi;
     439:     case CAN:
     440: gotcan:
     441:         if (--cancount <= 0) {
     442:             c = ZCAN; goto fifi;
     443:         }
     444:         switch (c = readline(1)) {
     445:         case TIMEOUT:
     446:             goto again;
     447:         case ZCRCW:
     448:             switch (readline(1)) {
     449:             case TIMEOUT:
     450:                 c = ERROR; goto fifi;
     451:             case RCDO:
     452:                 goto fifi;
     453:             default:
     454:                 goto agn2;
     455:             }
     456:         case RCDO:
     457:             goto fifi;
     458:         default:
     459:             break;
     460:         case CAN:
     461:             if (--cancount <= 0) {
     462:                 c = ZCAN; goto fifi;
     463:             }
     464:             goto again;
     465:         }
     466:     /* **** FALL THRU TO **** */
     467:     default:
     468: agn2:
     469:         if ( --n == 0) {
     470:             c = GCOUNT;  goto fifi;
     471:         }
     472:         if (eflag && ((c &= 0177) & 0140))
     473:             bttyout(c);
     474:         else if (eflag > 1)
     475:             bttyout(c);
     476: #ifdef UNIX
     477:         fflush(stderr);
     478: #endif
     479:         goto startover;
     480:     case ZPAD|0200:     /* This is what we want. */
     481:         Not8bit = c;
     482:     case ZPAD:      /* This is what we want. */
     483:         break;
     484:     }
     485:     cancount = 5;
     486: splat:
     487:     switch (c = noxrd7()) {
     488:     case ZPAD:
     489:         goto splat;
     490:     case RCDO:
     491:     case TIMEOUT:
     492:         goto fifi;
     493:     default:
     494:         goto agn2;
     495:     case ZDLE:      /* This is what we want. */
     496:         break;
     497:     }
     498:
     499:
     500:     Rxhlen = 4;     /* Set default length */
     501:     Rxframeind = c = noxrd7();
     502:     switch (c) {
     503:     case ZVBIN32:
     504:         if ((Rxhlen = c = zdlread()) < 0)
     505:             goto fifi;
     506:         if (c > ZMAXHLEN)
     507:             goto agn2;
     508:         Crc32r = 1;  c = zrbhd32(hdr); break;
     509:     case ZBIN32:
     510:         if (Usevhdrs)
     511:             goto agn2;
     512:         Crc32r = 1;  c = zrbhd32(hdr); break;
     513:     case ZVBINR32:
     514:         if ((Rxhlen = c = zdlread()) < 0)
     515:             goto fifi;
     516:         if (c > ZMAXHLEN)
     517:             goto agn2;
     518:         Crc32r = 2;  c = zrbhd32(hdr); break;
     519:     case ZBINR32:
     520:         if (Usevhdrs)
     521:             goto agn2;
     522:         Crc32r = 2;  c = zrbhd32(hdr); break;
     523:     case RCDO:
     524:     case TIMEOUT:
     525:         goto fifi;
     526:     case ZVBIN:
     527:         if ((Rxhlen = c = zdlread()) < 0)
     528:             goto fifi;
     529:         if (c > ZMAXHLEN)
     530:             goto agn2;
     531:         Crc32r = 0;  c = zrbhdr(hdr); break;
     532:     case ZBIN:
     533:         if (Usevhdrs)
     534:             goto agn2;
     535:         Crc32r = 0;  c = zrbhdr(hdr); break;
     536:     case ZVHEX:
     537:         if ((Rxhlen = c = zgethex()) < 0)
     538:             goto fifi;
     539:         if (c > ZMAXHLEN)
     540:             goto agn2;
     541:         Crc32r = 0;  c = zrhhdr(hdr); break;
     542:     case ZHEX:
     543:         if (Usevhdrs)
     544:             goto agn2;
     545:         Crc32r = 0;  c = zrhhdr(hdr); break;
     546:     case CAN:
     547:         goto gotcan;
     548:     default:
     549:         goto agn2;
     550:     }
     551:     for (n = Rxhlen; ++n < ZMAXHLEN; )  /* Clear unused hdr bytes */
     552:         hdr[n] = 0;
     553:     Rxpos = hdr[ZP3] & 0377;
     554:     Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
     555:     Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
     556:     Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
     557: fifi:
     558:     switch (c) {
     559:     case GOTCAN:
     560:         c = ZCAN;
     561:     /* **** FALL THRU TO **** */
     562:     case ZNAK:
     563:     case ZCAN:
     564:     case ERROR:
     565:     case TIMEOUT:
     566:     case RCDO:
     567:     case GCOUNT:
     568:         zperr("Got %s", frametypes[c+FTOFFSET]);
     569:     /* **** FALL THRU TO **** */
     570: #ifndef DSZ
     571:     default:
     572:         if (c >= -4 && c <= FRTYPES)
     573:             vfile("zgethdr: %c %d %s %lx", Rxframeind, Rxhlen,
     574:               frametypes[c+FTOFFSET], Rxpos);
     575:         else
     576:             vfile("zgethdr: %c %d %lx", Rxframeind, c, Rxpos);
     577: #endif
     578:     }
     579:     /* Use variable length headers if we got one */
     580:     if (c >= 0 && c <= FRTYPES && Rxframeind & 040)
     581:         Usevhdrs = 1;
     582:     return c;
     583: }
     584:
     585: /* Receive a binary style header (type and position) */
     586: zrbhdr(hdr)
     587: register char *hdr;
     588: {
     589:     register int c, n;
     590:     register unsigned short crc;
     591:
     592:     if ((c = zdlread()) & ~0377)
     593:         return c;
     594:     Rxtype = c;
     595:     crc = updcrc(c, 0);
     596:
     597:     for (n=Rxhlen; --n >= 0; ++hdr) {
     598:         if ((c = zdlread()) & ~0377)
     599:             return c;
     600:         crc = updcrc(c, crc);
     601:         *hdr = c;
     602:     }
     603:     if ((c = zdlread()) & ~0377)
     604:         return c;
     605:     crc = updcrc(c, crc);
     606:     if ((c = zdlread()) & ~0377)
     607:         return c;
     608:     crc = updcrc(c, crc);
     609:     if (crc & 0xFFFF) {
     610:         zperr(badcrc);
     611:         return ERROR;
     612:     }
     613: #ifdef ZMODEM
     614:     Protocol = ZMODEM;
     615: #endif
     616:     Zmodem = 1;
     617:     return Rxtype;
     618: }
     619:
     620: /* Receive a binary style header (type and position) with 32 bit FCS */
     621: zrbhd32(hdr)
     622: register char *hdr;
     623: {
     624:     register int c, n;
     625:     register UNSL long crc;
     626:
     627:     if ((c = zdlread()) & ~0377)
     628:         return c;
     629:     Rxtype = c;
     630:     crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
     631: #ifdef DEBUGZ
     632:     vfile("zrbhd32 c=%X  crc=%lX", c, crc);
     633: #endif
     634:
     635:     for (n=Rxhlen; --n >= 0; ++hdr) {
     636:         if ((c = zdlread()) & ~0377)
     637:             return c;
     638:         crc = UPDC32(c, crc);
     639:         *hdr = c;
     640: #ifdef DEBUGZ
     641:         vfile("zrbhd32 c=%X  crc=%lX", c, crc);
     642: #endif
     643:     }
     644:     for (n=4; --n >= 0;) {
     645:         if ((c = zdlread()) & ~0377)
     646:             return c;
     647:         crc = UPDC32(c, crc);
     648: #ifdef DEBUGZ
     649:         vfile("zrbhd32 c=%X  crc=%lX", c, crc);
     650: #endif
     651:     }
     652:     if (crc != 0xDEBB20E3) {
     653:         zperr(badcrc);
     654:         return ERROR;
     655:     }
     656: #ifdef ZMODEM
     657:     Protocol = ZMODEM;
     658: #endif
     659:     Zmodem = 1;
     660:     return Rxtype;
     661: }
     662:
     663:
     664: /* Receive a hex style header (type and position) */
     665: zrhhdr(hdr)
     666: char *hdr;
     667: {
     668:     register int c;
     669:     register unsigned short crc;
     670:     register int n;
     671:
     672:     if ((c = zgethex()) < 0)
     673:         return c;
     674:     Rxtype = c;
     675:     crc = updcrc(c, 0);
     676:
     677:     for (n=Rxhlen; --n >= 0; ++hdr) {
     678:         if ((c = zgethex()) < 0)
     679:             return c;
     680:         crc = updcrc(c, crc);
     681:         *hdr = c;
     682:     }
     683:     if ((c = zgethex()) < 0)
     684:         return c;
     685:     crc = updcrc(c, crc);
     686:     if ((c = zgethex()) < 0)
     687:         return c;
     688:     crc = updcrc(c, crc);
     689:     if (crc & 0xFFFF) {
     690:         zperr(badcrc); return ERROR;
     691:     }
     692:     switch ( c = readline(2)) {
     693:     case 0215:
     694:         Not8bit = c;
     695:         /* **** FALL THRU TO **** */
     696:     case 015:
     697:         /* Throw away possible cr/lf */
     698:         switch (c = readline(2)) {
     699:         case 012:
     700:             Not8bit |= c;
     701:         }
     702:     }
     703: #ifdef ZMODEM
     704:     Protocol = ZMODEM;
     705: #endif
     706:     Zmodem = 1;
     707:     if (c < 0)
     708:         return c;
     709:     return Rxtype;
     710: }
     711:
     712: /* Send a byte as two hex digits */
     713: zputhex(c)
     714: register int c;
     715: {
     716:     static char digits[]    = "0123456789abcdef";
     717:
     718: #ifdef DEBUGZ
     719:     if (Verbose>8)
     720:         vfile("zputhex: %02X", c);
     721: #endif
     722:     sendline(digits[(c&0xF0)>>4]);
     723:     sendline(digits[(c)&0xF]);
     724: }
     725:
     726: /*
     727:  * Send character c with ZMODEM escape sequence encoding.
     728:  *  Escape XON, XOFF. Escape CR following @ (Telenet net escape)
     729:  */
     730: zsendline(c)
     731: {
     732:
     733:     /* Quick check for non control characters */
     734:     if (c & 0140)
     735:         xsendline(lastsent = c);
     736:     else {
     737:         switch (c &= 0377) {
     738:         case ZDLE:
     739:             xsendline(ZDLE);
     740:             xsendline (lastsent = (c ^= 0100));
     741:             break;
     742:         case 015:
     743:         case 0215:
     744:             if (!Zctlesc && (lastsent & 0177) != '@')
     745:                 goto sendit;
     746:         /* **** FALL THRU TO **** */
     747:         case 020:
     748:         case 021:
     749:         case 023:
     750:         case 0220:
     751:         case 0221:
     752:         case 0223:
     753:             xsendline(ZDLE);
     754:             c ^= 0100;
     755:     sendit:
     756:             xsendline(lastsent = c);
     757:             break;
     758:         default:
     759:             if (Zctlesc && ! (c & 0140)) {
     760:                 xsendline(ZDLE);
     761:                 c ^= 0100;
     762:             }
     763:             xsendline(lastsent = c);
     764:         }
     765:     }
     766: }
     767:
     768: /* Decode two lower case hex digits into an 8 bit byte value */
     769: zgethex()
     770: {
     771:     register int c;
     772:
     773:     c = zgeth1();
     774: #ifdef DEBUGZ
     775:     if (Verbose>8)
     776:         vfile("zgethex: %02X", c);
     777: #endif
     778:     return c;
     779: }
     780: zgeth1()
     781: {
     782:     register int c, n;
     783:
     784:     if ((c = noxrd7()) < 0)
     785:         return c;
     786:     n = c - '0';
     787:     if (n > 9)
     788:         n -= ('a' - ':');
     789:     if (n & ~0xF)
     790:         return ERROR;
     791:     if ((c = noxrd7()) < 0)
     792:         return c;
     793:     c -= '0';
     794:     if (c > 9)
     795:         c -= ('a' - ':');
     796:     if (c & ~0xF)
     797:         return ERROR;
     798:     c += (n<<4);
     799:     return c;
     800: }
     801:
     802: /*
     803:  * Read a byte, checking for ZMODEM escape encoding
     804:  *  including CAN*5 which represents a quick abort
     805:  */
     806: zdlread()
     807: {
     808:     register int c;
     809:
     810: again:
     811:     /* Quick check for non control characters */
     812:     if ((c = readline(Rxtimeout)) & 0140)
     813:         return c;
     814:     switch (c) {
     815:     case ZDLE:
     816:         break;
     817:     case 023:
     818:     case 0223:
     819:     case 021:
     820:     case 0221:
     821:         goto again;
     822:     default:
     823:         if (Zctlesc && !(c & 0140)) {
     824:             goto again;
     825:         }
     826:         return c;
     827:     }
     828: again2:
     829:     if ((c = readline(Rxtimeout)) < 0)
     830:         return c;
     831:     if (c == CAN && (c = readline(Rxtimeout)) < 0)
     832:         return c;
     833:     if (c == CAN && (c = readline(Rxtimeout)) < 0)
     834:         return c;
     835:     if (c == CAN && (c = readline(Rxtimeout)) < 0)
     836:         return c;
     837:     switch (c) {
     838:     case CAN:
     839:         return GOTCAN;
     840:     case ZCRCE:
     841:     case ZCRCG:
     842:     case ZCRCQ:
     843:     case ZCRCW:
     844:         return (c | GOTOR);
     845:     case ZRUB0:
     846:         return 0177;
     847:     case ZRUB1:
     848:         return 0377;
     849:     case 023:
     850:     case 0223:
     851:     case 021:
     852:     case 0221:
     853:         goto again2;
     854:     default:
     855:         if (Zctlesc && ! (c & 0140)) {
     856:             goto again2;
     857:         }
     858:         if ((c & 0140) ==  0100)
     859:             return (c ^ 0100);
     860:         break;
     861:     }
     862:     if (Verbose>1)
     863:         zperr("Bad escape sequence %x", c);
     864:     return ERROR;
     865: }
     866:
     867: /*
     868:  * Read a character from the modem line with timeout.
     869:  *  Eat parity, XON and XOFF characters.
     870:  */
     871: noxrd7()
     872: {
     873:     register int c;
     874:
     875:     for (;;) {
     876:         if ((c = readline(Rxtimeout)) < 0)
     877:             return c;
     878:         switch (c &= 0177) {
     879:         case XON:
     880:         case XOFF:
     881:             continue;
     882:         default:
     883:             if (Zctlesc && !(c & 0140))
     884:                 continue;
     885:         case '\r':
     886:         case '\n':
     887:         case ZDLE:
     888:             return c;
     889:         }
     890:     }
     891: }
     892:
     893: /* Store long integer pos in Txhdr */
     894: stohdr(pos)
     895: long pos;
     896: {
     897:     Txhdr[ZP0] = pos;
     898:     Txhdr[ZP1] = pos>>8;
     899:     Txhdr[ZP2] = pos>>16;
     900:     Txhdr[ZP3] = pos>>24;
     901: }
     902:
     903: /* Recover a long integer from a header */
     904: long
     905: rclhdr(hdr)
     906: register char *hdr;
     907: {
     908:     register long l;
     909:
     910:     l = (hdr[ZP3] & 0377);
     911:     l = (l << 8) | (hdr[ZP2] & 0377);
     912:     l = (l << 8) | (hdr[ZP1] & 0377);
     913:     l = (l << 8) | (hdr[ZP0] & 0377);
     914:     return l;
     915: }
     916:
     917: /* End of zm.c */

#### Defined functions

garbitch defined in line 404; used 3 times

- in line 332, 339, 394

noxrd7 defined in line 871; used 4 times

- in line 487, 501, 784, 791

rclhdr defined in line 904; used 5 times

- in line 123, 193
- in /usr/src/local/zmodem/rz.c line 1303, 1339
- in /usr/src/local/zmodem/zmodem.h line 119

stohdr defined in line 894; used 19 times

- in /usr/src/local/zmodem/rz.c line 1142-1144(2), 1185, 1192, 1202-1204(2), 1278, 1401, 1413, 1500
- in /usr/src/local/zmodem/sz.c line 577, 1386-1390(2), 1522, 1592, 1697, 1817, 1896, 1929

zdlread defined in line 806; used 23 times

- in line 301, 309-312(2), 356, 365-374(4), 504, 514, 527, 592, 598-606(3), 627, 636, 645
- in /usr/src/local/zmodem/zmr.c line 111, 120-129(4)

zgeth1 defined in line 780; used 1 times

- in line 773

zgethdr defined in line 421; used 9 times

- in /usr/src/local/zmodem/rz.c line 1160, 1209, 1281
- in /usr/src/local/zmodem/sz.c line 1384, 1532, 1565, 1848, 1898, 1936

zgethex defined in line 769; used 5 times

- in line 537, 672, 678-686(3)

zputhex defined in line 713; used 5 times

- in line 198-210(5)

zrbhd32 defined in line 621; used 4 times

- in line 508-512(2), 518-522(2)

zrbhdr defined in line 586; used 2 times

- in line 531-535(2)

zrdat32 defined in line 346; used 1 times

- in line 294

zrdata defined in line 284; used 6 times

- in /usr/src/local/zmodem/rz.c line 1176, 1184, 1200, 1296, 1358-1360(2)

zrhhdr defined in line 665; used 2 times

- in line 541-545(2)

zsbh32 defined in line 161; used 2 times

- in line 133-136(2)

zsbhdr defined in line 115; used 7 times

- in /usr/src/local/zmodem/sz.c line 1530, 1562, 1593, 1698, 1818, 1885, 1931

zsda32 defined in line 255; used 1 times

- in line 236

zsdata defined in line 226; used 7 times

- in /usr/src/local/zmodem/sz.c line 1531, 1563, 1758, 1786, 1800, 1806, 1932

zsendline defined in line 730; used 25 times

- in line 140-153(5), 169-179(4), 242, 248(2), 267, 275
- in /usr/src/local/zmodem/zmr.c line 49-51(2), 60-68(4), 75-83(4), 94

zshhdr defined in line 185; used 17 times

- in /usr/src/local/zmodem/rz.c line 1156, 1180, 1186-1193(3), 1207, 1215, 1279, 1402, 1414, 1503
- in /usr/src/local/zmodem/sz.c line 580, 1387-1391(2), 1506, 1527, 1897

#### Defined variables

Altcan defined in line 76; never used
Attn defined in line 75; used 5 times

- in /usr/src/local/zmodem/rz.c line 256, 1184, 1327, 1347, 1379

Crc32r defined in line 71; used 10 times

- in line 292, 508-512(2), 518-522(2), 531-535(2), 541-545(2)
- in /usr/src/local/zmodem/rz.c line 1352

Crc32t defined in line 69; used 4 times

- in line 131, 203, 234
- in /usr/src/local/zmodem/sz.c line 1757

Rxcount defined in line 63; used 18 times

- in line 299, 319-321(2), 354, 381-383(2)
- in /usr/src/local/zmodem/rz.c line 1394-1400(3), 1408-1412(3), 1419-1432(6)

Rxframeind defined in line 60; used 5 times

- in line 427, 501, 573-580(3)

Rxhdr defined in line 64; used 23 times

- in /usr/src/local/zmodem/rz.c line 1160-1162(2), 1170-1173(4), 1183, 1199, 1209, 1281, 1303, 1339
- in /usr/src/local/zmodem/sz.c line 1384, 1394-1398(4), 1503, 1532, 1565, 1848, 1898, 1936

Rxhlen defined in line 62; used 10 times

- in line 500-504(2), 514, 527, 537, 551, 573, 597, 635, 677

Rxpos defined in line 66; used 24 times

- in line 553-556(7), 574-576(2)
- in /usr/src/local/zmodem/sz.c line 1386, 1580-1581(2), 1589, 1625-1630(3), 1846, 1861-1866(3), 1872-1876(3), 1958

Rxtimeout defined in line 51; used 20 times

- in line 433, 812, 829-835(4), 876
- in /usr/src/local/zmodem/rz.c line 272, 313-314(3)
- in /usr/src/local/zmodem/sz.c line 386, 468-469(3), 898, 927, 976, 1003, 1934

Rxtype defined in line 61; used 7 times

- in line 427, 594, 617, 629, 660, 674, 709

Txfcs32 defined in line 68; used 5 times

- in line 131
- in /usr/src/local/zmodem/sz.c line 1396, 1494, 1619-1621(2)

Txhdr defined in line 65; used 42 times

- in line 897-900(4)
- in /usr/src/local/zmodem/rz.c line 1147-1156(6), 1180, 1186-1193(3), 1207, 1215, 1279, 1402, 1414, 1503
- in /usr/src/local/zmodem/sz.c line 579-580(2), 1387-1391(2), 1506, 1524-1530(4), 1556-1562(6), 1593, 1698, 1818, 1885, 1897, 1930-1931(2)

Txpos defined in line 67; used 8 times

- in /usr/src/local/zmodem/sz.c line 1630, 1697, 1757-1759(2), 1797, 1817, 1864, 1876

Usevhdrs defined in line 73; used 16 times

- in line 122, 133-138(3), 168, 192-196(2), 510, 520, 533, 543, 581
- in /usr/src/local/zmodem/rz.c line 1163, 1174
- in /usr/src/local/zmodem/sz.c line 1395, 1935

Zendnames defined in line 225; used 3 times

- in line 232, 322, 384

Znulls defined in line 74; used 2 times

- in line 126
- in /usr/src/local/zmodem/sz.c line 376

badcrc defined in line 112; used 5 times

- in line 316, 378, 610, 653, 690

frametypes defined in line 81; used 4 times

- in line 123, 193, 568, 574

#### Defined macros

FRTYPES defined in line 108; used 2 times

- in line 572, 580

FTOFFSET defined in line 86; used 4 times

- in line 123, 193, 568, 574

UNSL defined in line 55; used 6 times

- in line 54, 165, 259, 350, 625
- in /usr/src/local/zmodem/sz.c line 1551

#### Usage of this include

zm.c used 2 times

- in /usr/src/local/zmodem/rz.c line 241
- in /usr/src/local/zmodem/sz.c line 357

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