home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / rzsz_3_24_3_src.lzh / zm.c < prev    next >
Text File  |  1993-11-03  |  20KB  |  998 lines

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