home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / TERMS / ZMP-SRC.LZH / ZZM.C < prev    next >
Text File  |  2000-06-30  |  9KB  |  457 lines

  1. /*
  2.  *   Z M . C
  3.  *    ZMODEM protocol primitives
  4.  *    07-28-87  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. #define  ZM
  17.  
  18. #undef DEBUG
  19.  
  20. #include "zmp.h"
  21. #include "zmodem.h"
  22.  
  23. #ifdef   AZTEC_C
  24. #include "libc.h"
  25. #else
  26. #include <stdio.h>
  27. #endif
  28.  
  29. long updc32();
  30.  
  31.  
  32. /* Send ZMODEM binary header hdr of type type */
  33. zsbhdr(type, hdr)
  34. char *hdr;
  35. {
  36.     static int n;
  37.     static unsigned crc;
  38.  
  39. #ifdef DEBUG
  40.     printf("\nSending BINARY header Type %d:",type);
  41.     for (n = 0; n < 4; n++)
  42.         prhex( *(hdr + n));
  43.     printf("\n");
  44. #endif
  45.  
  46.     if (type == ZDATA)
  47.         for (n = Znulls; --n >=0; )
  48.             zsendline(0);
  49.  
  50.     xmchout(ZPAD); 
  51.     xmchout(ZDLE);
  52.  
  53.     if (Crc32t=Txfcs32)
  54.         zsbh32(hdr, type);
  55.     else {
  56.         xmchout(ZBIN); 
  57.         zsendline(type); 
  58.         crc = updcrc(type, 0);
  59.  
  60.         for (n=4; --n >= 0; ++hdr) {
  61.             zsendline(*hdr);
  62.             crc = updcrc((0377& *hdr), crc);
  63.         }
  64.         crc = updcrc(0,updcrc(0,crc));
  65.         zsendline(crc>>8);
  66.         zsendline(crc);
  67.     }
  68.     if (type != ZDATA)
  69.         purgeline();
  70. }
  71.  
  72.  
  73. /* Send ZMODEM binary header hdr of type type */
  74.  
  75. zsbh32(hdr, type)
  76. char *hdr;
  77. {
  78.     static int n;
  79.     static long crc;
  80.  
  81.     xmchout(ZBIN32);  
  82.     zsendline(type);
  83.     crc = 0xFFFFFFFFL; 
  84.     crc = updc32(type, crc);
  85.  
  86.     for (n=4; --n >= 0; ++hdr) {
  87.         crc = updc32((0377 & *hdr), crc);
  88.         zsendline(*hdr);
  89.     }
  90.     crc = ~crc;
  91.     for (n=4; --n >= 0;) {
  92.         zsendline((int)crc);
  93.         crc >>= 8;
  94.     }
  95. }
  96.  
  97. /* Send ZMODEM HEX header hdr of type type */
  98.  
  99. zshhdr(type, hdr)
  100. char *hdr;
  101. {
  102.     static int n;
  103.     static unsigned crc;
  104.  
  105. #ifdef DEBUG
  106.     printf("\nSending HEX header Type %d:",type);
  107.     for (n = 0; n < 4; n++)
  108.         prhex( *(hdr + n));
  109.     printf("\n");
  110. #endif
  111.  
  112.    xmchout(ZPAD); 
  113.    xmchout(ZPAD); 
  114.    xmchout(ZDLE); 
  115.    xmchout(ZHEX);
  116.     zputhex(type);
  117.     Crc32t = 0;
  118.  
  119.     crc = updcrc(type, 0);
  120.     for (n=4; --n >= 0; ++hdr) {
  121.         zputhex(*hdr); 
  122.         crc = updcrc((0377 & *hdr), crc);
  123.     }
  124.     crc = updcrc(0,updcrc(0,crc));
  125.     zputhex(crc>>8); 
  126.     zputhex(crc);
  127.  
  128.     /* Make it printable on remote machine */
  129.    xmchout(CR); 
  130.    xmchout(LF);
  131.     /*
  132.      * Uncork the remote in case a fake XOFF has stopped data flow
  133.      */
  134.     if (type != ZFIN && type != ZACK)
  135.        xmchout(CTRLQ);
  136.     purgeline();
  137. }
  138.  
  139. /*
  140.  * Send binary array buf of length length, with ending ZDLE sequence frameend
  141.  */
  142. zsdata(buf, length, frameend)
  143. int length, frameend;
  144. char *buf;
  145. {
  146.     static unsigned crc;
  147.  
  148.     if (Crc32t)
  149.         zsda32(buf, length, frameend);
  150.     else {
  151.         crc = 0;
  152.         for (;--length >= 0; ++buf) {
  153.             zsendline(*buf); 
  154.             crc = updcrc((0377 & *buf), crc);
  155.         }
  156.         xmchout(ZDLE); 
  157.         xmchout(frameend);
  158.         crc = updcrc(frameend, crc);
  159.  
  160.         crc = updcrc(0,updcrc(0,crc));
  161.         zsendline(crc>>8); 
  162.         zsendline(crc);
  163.     }
  164.     if (frameend == ZCRCW) {
  165.         xmchout(XON);  
  166.         purgeline();
  167.     }
  168. }
  169.  
  170. zsda32(buf, length, frameend)
  171. char *buf;
  172. int length, frameend;
  173. {
  174.     static long crc;
  175.  
  176.     crc = 0xFFFFFFFFL;
  177.     for (;--length >= 0;++buf) {
  178.         crc = updc32((0377 & *buf), crc);
  179.         zsendline(*buf);
  180.     }
  181.     xmchout(ZDLE); 
  182.     xmchout(frameend);
  183.     crc = updc32(frameend, crc);
  184.  
  185.     crc = ~crc;
  186.     for (length=4; --length >= 0;) {
  187.         zsendline((int)crc);  
  188.         crc >>= 8;
  189.     }
  190. }
  191.  
  192. /*
  193.  * Receive array buf of max length with ending ZDLE sequence
  194.  *  and CRC.  Returns the ending character or error code.
  195.  *  NB: On errors may store length+1 bytes!
  196.  */
  197. zrdata(buf, length)
  198. char *buf;
  199. {
  200.     static int c;
  201.     static unsigned crc;
  202.     static char *end;
  203.     static int d;
  204.  
  205.     if (Rxframeind == ZBIN32)
  206.         return zrdat32(buf, length);
  207.  
  208.     crc = Rxcount = 0;  
  209.     end = buf + length;
  210.     while (buf <= end) {
  211.         if ((c = zdlread()) & ~0377) {
  212. crcfoo:
  213.             switch (c) {
  214.             case GOTCRCE:
  215.             case GOTCRCG:
  216.             case GOTCRCQ:
  217.             case GOTCRCW:
  218.                 crc = updcrc((d=c)&0377, crc);
  219.                 if ((c = zdlread()) & ~0377)
  220.                     goto crcfoo;
  221.                 crc = updcrc(c, crc);
  222.                 if ((c = zdlread()) & ~0377)
  223.                     goto crcfoo;
  224.                 crc = updcrc(c, crc);
  225.                 if (crc & 0xFFFF) {
  226.                     zperr("Bad data CRC",TRUE);
  227.  
  228. #ifdef    DEBUG
  229.                     printf("\nCRC = %u\n",crc);
  230. #endif
  231.  
  232.                     return NERROR;
  233.                 }
  234.                 Rxcount = length - (end - buf);
  235.                 return d;
  236.             case GOTCAN:
  237.                 zperr("Sender CANceled",TRUE);
  238.                 return ZCAN;
  239.             case TIMEOUT:
  240.                 zperr("TIMEOUT",TRUE);
  241.                 return c;
  242.             default:
  243.                 zperr("Bad data subpkt",TRUE);
  244.                 return c;
  245.             }
  246.         }
  247.         *buf++ = c;
  248.         crc = updcrc(c, crc);
  249.     }
  250.     zperr("Subpkt too long",TRUE);
  251.     return NERROR;
  252. }
  253.  
  254. zrdat32(buf, length)
  255. char *buf;
  256. {
  257.     static int c, d;
  258.     static long crc;
  259.     static char *end;
  260.  
  261. #ifdef DEBUG
  262.     printf("\n(32)\n");
  263. #endif
  264.  
  265.     crc = 0xFFFFFFFFL;  
  266.     Rxcount = 0;  
  267.     end = buf + length;
  268.     while (buf <= end) {
  269.         if ((c = zdlread()) & ~0377) {
  270. crcfoo:
  271.             switch (c) {
  272.             case GOTCRCE:
  273.             case GOTCRCG:
  274.             case GOTCRCQ:
  275.             case GOTCRCW:
  276.                 d = c;  
  277.                 c &= 0377;
  278.                 crc = updc32(c, crc);
  279.                 if ((c = zdlread()) & ~0377)
  280.                     goto crcfoo;
  281.                 crc = updc32(c, crc);
  282.                 if ((c = zdlread()) & ~0377)
  283.                     goto crcfoo;
  284.                 crc = updc32(c, crc);
  285.                 if ((c = zdlread()) & ~0377)
  286.                     goto crcfoo;
  287.                 crc = updc32(c, crc);
  288.                 if ((c = zdlread()) & ~0377)
  289.                     goto crcfoo;
  290.                 crc = updc32(c, crc);
  291.                 if (crc != 0xDEBB20E3) {
  292.                     zperr("Bad data CRC",TRUE);
  293.                     return NERROR;
  294.                 }
  295.                 Rxcount = length - (end - buf);
  296.                 return d;
  297.             case GOTCAN:
  298.                 zperr("Sender CANceled",TRUE);
  299.                 return ZCAN;
  300.             case TIMEOUT:
  301.                 zperr("TIMEOUT",TRUE);
  302.                 return c;
  303.             default:
  304.                 zperr("Bad data subpkt",TRUE);
  305.                 return c;
  306.             }
  307.         }
  308.         *buf++ = c;
  309.         crc = updc32(c, crc);
  310.     }
  311.     zperr("Subpkt too long",TRUE);
  312.     return NERROR;
  313. }
  314.  
  315.  
  316. /*
  317.  * Read a ZMODEM header to hdr, either binary or hex.
  318.  *  eflag controls local display of non zmodem characters:
  319.  *    0:  no display
  320.  *    1:  display printing characters only
  321.  *    2:  display all non ZMODEM characters
  322.  *  On success, set Zmodem to 1, set Rxpos and return type of header.
  323.  *   Otherwise return negative on error.
  324.  *   Return NERROR instantly if ZCRCW sequence, for fast error recovery.
  325.  */
  326. zgethdr(hdr, eflag)
  327. char *hdr;
  328. int eflag;
  329. {
  330.     static int c, n, cancount;
  331.  
  332.     n = Zrwindow + Baudrate;       /* Max bytes before start of frame */
  333.     Rxframeind = Rxtype = 0;
  334.  
  335. startover:
  336.     cancount = 5;
  337. again:
  338.     /* Return immediate NERROR if ZCRCW sequence seen */
  339.     switch (c = readline(Rxtimeout)) {
  340.     case RCDO:
  341.     case TIMEOUT:
  342.         goto fifi;
  343.     case CAN:
  344. gotcan:
  345.         if (--cancount <= 0) {
  346.             c = ZCAN; 
  347.             goto fifi;
  348.         }
  349.         switch (c = readline(INTRATIME)) {
  350.         case TIMEOUT:
  351.             goto again;
  352.         case ZCRCW:
  353.             c = NERROR;
  354.             /* **** FALL THRU TO **** */
  355.         case RCDO:
  356.             goto fifi;
  357.         default:
  358.             break;
  359.         case CAN:
  360.             if (--cancount <= 0) {
  361.                 c = ZCAN; 
  362.                 goto fifi;
  363.             }
  364.             goto again;
  365.         }
  366.         /* **** FALL THRU TO **** */
  367.     default:
  368. agn2:
  369.         if ( --n == 0) {
  370.             zperr("Grbg ct exceeded",TRUE);
  371.             return(NERROR);
  372.         }
  373.         goto startover;
  374.     case ZPAD|0200:        /* This is what we want. */
  375.     case ZPAD:        /* This is what we want. */
  376.         break;
  377.     }
  378.     cancount = 5;
  379. splat:
  380.     switch (c = noxrd7()) {
  381.     case ZPAD:
  382.         goto splat;
  383.     case RCDO:
  384.     case TIMEOUT:
  385.         goto fifi;
  386.     default:
  387.         goto agn2;
  388.     case ZDLE:        /* This is what we want. */
  389.         break;
  390.     }
  391.  
  392.     switch (c = noxrd7()) {
  393.     case RCDO:
  394.     case TIMEOUT:
  395.         goto fifi;
  396.     case ZBIN:
  397.         Rxframeind = ZBIN;  
  398.         Crc32 = FALSE;
  399.         c =  zrbhdr(hdr);
  400.         break;
  401.     case ZBIN32:
  402.         Crc32 = Rxframeind = ZBIN32;
  403.         c =  zrb32hdr(hdr);
  404.         break;
  405.     case ZHEX:
  406.         Rxframeind = ZHEX;  
  407.         Crc32 = FALSE;
  408.         c =  zrhhdr(hdr);
  409.         break;
  410.     case CAN:
  411.         goto gotcan;
  412.     default:
  413.         goto agn2;
  414.     }
  415.     Rxpos = (unsigned)(hdr[ZP3] & 0377);
  416.     Rxpos = (Rxpos<<8) + (unsigned)(hdr[ZP2] & 0377);
  417.     Rxpos = (Rxpos<<8) + (unsigned)(hdr[ZP1] & 0377);
  418.     Rxpos = (Rxpos<<8) + (unsigned)(hdr[ZP0] & 0377);
  419. fifi:
  420.     switch (c) {
  421.     case GOTCAN:
  422.         c = ZCAN;
  423.         /* **** FALL THRU TO **** */
  424.     case ZNAK:
  425.     case ZCAN:
  426.     case NERROR:
  427.     case TIMEOUT:
  428.     case RCDO:
  429.       sprintf(Buf,"Got %s", frametypes[c+FTOFFSET]);
  430.         zperr(Buf,TRUE);
  431.         /* **** FALL THRU TO **** */
  432.     default:
  433.       break;
  434.     }
  435.     return c;
  436. }
  437.  
  438. #ifdef DEBUG
  439.  
  440. /* Print a byte in hex on the console */
  441.  
  442. prhex(byte)
  443. char byte;
  444.  
  445. {
  446.     static char digits[] = "0123456789abcdef";
  447.     char hi, lo;
  448.  
  449.     hi = digits[(byte & 0xf0) >> 4];
  450.     lo = digits[byte & 0x0f];
  451.     printf(" %c%c",hi,lo);
  452. }
  453.  
  454. #endif
  455.  
  456. /***************************** End of hzm.c *********************************/
  457.