C   18

zm.c

Guest on 5th May 2022 10:48:57 PM

  1. /*
  2.  *   Z M . C
  3.  *    ZMODEM protocol primitives
  4.  *      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. #ifndef CANFDX
  17. #include "zmodem.h"
  18. #endif
  19. int Rxtimeout = 100;            /* Tenths of seconds to wait for something */
  20.  
  21. #ifndef UNSL
  22. #define UNSL
  23. #endif
  24.  
  25.  
  26. /* Globals used by ZMODEM functions */
  27. int Rxframeind;         /* ZBIN ZBIN32, or ZHEX type of frame received */
  28. int Rxtype;             /* Type of header received */
  29. int Rxcount;            /* Count of data bytes received */
  30. char Rxhdr[4];          /* Received header */
  31. char Txhdr[4];          /* Transmitted header */
  32. long Rxpos;             /* Received file position */
  33. long Txpos;             /* Transmitted file position */
  34. int Txfcs32;            /* TURE means send binary frames with 32 bit FCS */
  35. int Crc32t;             /* Display flag indicating 32 bit CRC being sent */
  36. int Crc32;              /* Display flag indicating 32 bit CRC being received */
  37. int Znulls;             /* Number of nulls to send at beginning of ZDATA hdr */
  38. char Attn[ZATTNLEN+1];  /* Attention string rx sends to tx on err */
  39.  
  40. static int lastsent;    /* Last char we sent */
  41. static int Not8bit;     /* Seven bits seen on header */
  42.  
  43. static char *frametypes[] = {
  44.         "Carrier Lost",         /* -3 */
  45.         "TIMEOUT",              /* -2 */
  46.         "ERROR",                /* -1 */
  47. #define FTOFFSET 3
  48.         "ZRQINIT",
  49.         "ZRINIT",
  50.         "ZSINIT",
  51.         "ZACK",
  52.         "ZFILE",
  53.         "ZSKIP",
  54.         "ZNAK",
  55.         "ZABORT",
  56.         "ZFIN",
  57.         "ZRPOS",
  58.         "ZDATA",
  59.         "ZEOF",
  60.         "ZFERR",
  61.         "ZCRC",
  62.         "ZCHALLENGE",
  63.         "ZCOMPL",
  64.         "ZCAN",
  65.         "ZFREECNT",
  66.         "ZCOMMAND",
  67.         "ZSTDERR",
  68.         "xxxxx"
  69. #define FRTYPES 22      /* Total number of frame types in this array */
  70.                         /*  not including psuedo negative entries */
  71. };
  72.  
  73. static char badcrc[] = "Bad CRC";
  74.  
  75. /* Send ZMODEM binary header hdr of type type */
  76. void zsbhdr(type, hdr)
  77. int type;
  78. register char *hdr;
  79. {
  80.         register int n;
  81.         register unsigned short crc;
  82.  
  83.         vfile("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  84.         if (type == ZDATA)
  85.                 for (n = Znulls; --n >=0; )
  86.                         xsendline(0);
  87.  
  88.         xsendline(ZPAD); xsendline(ZDLE);
  89.  
  90.         if ((Crc32t=Txfcs32))
  91.                 zsbh32(hdr, type);
  92.         else {
  93.                 xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0);
  94.  
  95.                 for (n=4; --n >= 0; ++hdr) {
  96.                         zsendline(*hdr);
  97.                         crc = updcrc((0377& *hdr), crc);
  98.                 }
  99.                 crc = updcrc(0,updcrc(0,crc));
  100.                 zsendline(crc>>8);
  101.                 zsendline(crc);
  102.         }
  103.         if (type != ZDATA)
  104.                 flushmo();
  105. }
  106.  
  107.  
  108. /* Send ZMODEM binary header hdr of type type */
  109. void zsbh32(hdr, type)
  110. register char *hdr;
  111. int type;
  112. {
  113.         register int n;
  114.         register UNSL long crc;
  115.  
  116.         xsendline(ZBIN32);  zsendline(type);
  117.         crc = 0xFFFFFFFFL; crc = UPDC32(type, crc);
  118.  
  119.         for (n=4; --n >= 0; ++hdr) {
  120.                 crc = UPDC32((0377 & *hdr), crc);
  121.                 zsendline(*hdr);
  122.         }
  123.         crc = ~crc;
  124.         for (n=4; --n >= 0;) {
  125.                 zsendline((int)crc);
  126.                 crc >>= 8;
  127.         }
  128. }
  129.  
  130. /* Send ZMODEM HEX header hdr of type type */
  131. void zshhdr(type, hdr)
  132. int type;
  133. register char *hdr;
  134. {
  135.         register int n;
  136.         register unsigned short crc;
  137.  
  138.         vfile("zshhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr));
  139.         sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX);
  140.         zputhex(type);
  141.         Crc32t = 0;
  142.  
  143.         crc = updcrc(type, 0);
  144.         for (n=4; --n >= 0; ++hdr) {
  145.                 zputhex(*hdr); crc = updcrc((0377 & *hdr), crc);
  146.         }
  147.         crc = updcrc(0,updcrc(0,crc));
  148.         zputhex(crc>>8); zputhex(crc);
  149.  
  150.         /* Make it printable on remote machine */
  151.         sendline(015); sendline(0212);
  152.         /*
  153.          * Uncork the remote in case a fake XOFF has stopped data flow
  154.          */
  155.         if (type != ZFIN && type != ZACK)
  156.                 sendline(021);
  157.         flushmo();
  158. }
  159.  
  160. /*
  161.  * Send binary array buf of length length, with ending ZDLE sequence frameend
  162.  */
  163. static char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
  164.  
  165. void zsdata(buf, length, frameend)
  166. register char *buf;
  167. int length;
  168. int frameend;
  169. {
  170.         register unsigned short crc;
  171.  
  172.         vfile("zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]);
  173.         if (Crc32t)
  174.                 zsda32(buf, length, frameend);
  175.         else {
  176.                 crc = 0;
  177.                 for (;--length >= 0; ++buf) {
  178.                         zsendline(*buf); crc = updcrc((0377 & *buf), crc);
  179.                 }
  180.                 xsendline(ZDLE); xsendline(frameend);
  181.                 crc = updcrc(frameend, crc);
  182.  
  183.                 crc = updcrc(0,updcrc(0,crc));
  184.                 zsendline(crc>>8); zsendline(crc);
  185.         }
  186.         if (frameend == ZCRCW) {
  187.                 xsendline(XON);  flushmo();
  188.         }
  189. }
  190.  
  191. void zsda32(buf, length, frameend)
  192. register char *buf;
  193. int length;
  194. int frameend;
  195. {
  196.         register int c;
  197.         register UNSL long crc;
  198.  
  199.         crc = 0xFFFFFFFFL;
  200.         for (;--length >= 0; ++buf) {
  201.                 c = *buf & 0377;
  202.                 if (c & 0140)
  203.                         xsendline(lastsent = c);
  204.                 else
  205.                         zsendline(c);
  206.                 crc = UPDC32(c, crc);
  207.         }
  208.         xsendline(ZDLE); xsendline(frameend);
  209.         crc = UPDC32(frameend, crc);
  210.  
  211.         crc = ~crc;
  212.         for (length=4; --length >= 0;) {
  213.                 zsendline((int)crc);  crc >>= 8;
  214.         }
  215. }
  216.  
  217. /*
  218.  * Receive array buf of max length with ending ZDLE sequence
  219.  *  and CRC.  Returns the ending character or error code.
  220.  *  NB: On errors may store length+1 bytes!
  221.  */
  222. int zrdata(buf, length)
  223. register char *buf;
  224. int length;
  225. {
  226.         register int c;
  227.         register unsigned short crc;
  228.         register char *end;
  229.         register int d;
  230.  
  231.         if (Rxframeind == ZBIN32)
  232.                 return zrdat32(buf, length);
  233.  
  234.         crc = Rxcount = 0;  end = buf + length;
  235.         while (buf <= end) {
  236.                 if ((c = zdlread()) & ~0377) {
  237. crcfoo:
  238.                         switch (c) {
  239.                         case GOTCRCE:
  240.                         case GOTCRCG:
  241.                         case GOTCRCQ:
  242.                         case GOTCRCW:
  243.                                 crc = updcrc((((d=c))&0377), crc);
  244.                                 if ((c = zdlread()) & ~0377)
  245.                                         goto crcfoo;
  246.                                 crc = updcrc(c, crc);
  247.                                 if ((c = zdlread()) & ~0377)
  248.                                         goto crcfoo;
  249.                                 crc = updcrc(c, crc);
  250.                                 if (crc & 0xFFFF) {
  251.                                         zperr(badcrc);
  252.                                         return ERROR;
  253.                                 }
  254.                                 Rxcount = length - (end - buf);
  255.                                 vfile("zrdata: %d  %s", Rxcount,
  256.                                  Zendnames[(d-GOTCRCE)&3]);
  257.                                 return d;
  258.                         case GOTCAN:
  259.                                 zperr("Sender Canceled");
  260.                                 return ZCAN;
  261.                         case TIMEOUT:
  262.                                 zperr("TIMEOUT");
  263.                                 return c;
  264.                         default:
  265.                                 zperr("Bad data subpacket");
  266.                                 return c;
  267.                         }
  268.                 }
  269.                 *buf++ = c;
  270.                 crc = updcrc(c, crc);
  271.         }
  272.         zperr("Data subpacket too long");
  273.         return ERROR;
  274. }
  275.  
  276. int zrdat32(buf, length)
  277. register char *buf;
  278. int length;
  279. {
  280.         register int c;
  281.         register UNSL long crc;
  282.         register char *end;
  283.         register int d;
  284.  
  285.         crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  286.         while (buf <= end) {
  287.                 if ((c = zdlread()) & ~0377) {
  288. crcfoo:
  289.                         switch (c) {
  290.                         case GOTCRCE:
  291.                         case GOTCRCG:
  292.                         case GOTCRCQ:
  293.                         case GOTCRCW:
  294.                                 d = c;  c &= 0377;
  295.                                 crc = UPDC32(c, crc);
  296.                                 if ((c = zdlread()) & ~0377)
  297.                                         goto crcfoo;
  298.                                 crc = UPDC32(c, crc);
  299.                                 if ((c = zdlread()) & ~0377)
  300.                                         goto crcfoo;
  301.                                 crc = UPDC32(c, crc);
  302.                                 if ((c = zdlread()) & ~0377)
  303.                                         goto crcfoo;
  304.                                 crc = UPDC32(c, crc);
  305.                                 if ((c = zdlread()) & ~0377)
  306.                                         goto crcfoo;
  307.                                 crc = UPDC32(c, crc);
  308.                                 if (crc != 0xDEBB20E3) {
  309.                                         zperr(badcrc);
  310.                                         return ERROR;
  311.                                 }
  312.                                 Rxcount = length - (end - buf);
  313.                                 vfile("zrdat32: %d %s", Rxcount,
  314.                                  Zendnames[(d-GOTCRCE)&3]);
  315.                                 return d;
  316.                         case GOTCAN:
  317.                                 zperr("Sender Canceled");
  318.                                 return ZCAN;
  319.                         case TIMEOUT:
  320.                                 zperr("TIMEOUT");
  321.                                 return c;
  322.                         default:
  323.                                 zperr("Bad data subpacket");
  324.                                 return c;
  325.                         }
  326.                 }
  327.                 *buf++ = c;
  328.                 crc = UPDC32(c, crc);
  329.         }
  330.         zperr("Data subpacket too long");
  331.         return ERROR;
  332. }
  333.  
  334.  
  335. /*
  336.  * Read a ZMODEM header to hdr, either binary or hex.
  337.  *  eflag controls local display of non zmodem characters:
  338.  *      0:  no display
  339.  *      1:  display printing characters only
  340.  *      2:  display all non ZMODEM characters
  341.  *  On success, set Zmodem to 1, set Rxpos and return type of header.
  342.  *   Otherwise return negative on error.
  343.  *   Return ERROR instantly if ZCRCW sequence, for fast error recovery.
  344.  */
  345. int zgethdr(hdr, eflag)
  346. char *hdr;
  347. int eflag;
  348. {
  349.         register int c, n, cancount;
  350.  
  351.         n = Zrwindow + Baudrate;        /* Max bytes before start of frame */
  352.         Rxframeind = Rxtype = 0;
  353.  
  354. startover:
  355.         cancount = 5;
  356. again:
  357.         /* Return immediate ERROR if ZCRCW sequence seen */
  358.         switch (c = readline(Rxtimeout)) {
  359.         case RCDO:
  360.         case TIMEOUT:
  361.                 goto fifi;
  362.         case CAN:
  363. gotcan:
  364.                 if (--cancount <= 0) {
  365.                         c = ZCAN; goto fifi;
  366.                 }
  367.                 switch (c = readline(1)) {
  368.                 case TIMEOUT:
  369.                         goto again;
  370.                 case ZCRCW:
  371.                         c = ERROR;
  372.                 /* **** FALL THRU TO **** */
  373.                 case RCDO:
  374.                         goto fifi;
  375.                 default:
  376.                         break;
  377.                 case CAN:
  378.                         if (--cancount <= 0) {
  379.                                 c = ZCAN; goto fifi;
  380.                         }
  381.                         goto again;
  382.                 }
  383.         /* **** FALL THRU TO **** */
  384.         default:
  385. agn2:
  386.                 if ( --n == 0) {
  387.                         zperr("Garbage count exceeded");
  388.                         return(ERROR);
  389.                 }
  390.                 if (eflag && ((c &= 0177) & 0140))
  391.                         bttyout(c);
  392.                 else if (eflag > 1)
  393.                         bttyout(c);
  394. #ifdef UNIX
  395.                 fflush(stderr);
  396. #endif
  397.                 goto startover;
  398.         case ZPAD|0200:         /* This is what we want. */
  399.                 Not8bit = c;
  400.         case ZPAD:              /* This is what we want. */
  401.                 break;
  402.         }
  403.         cancount = 5;
  404. splat:
  405.         switch (c = noxrd7()) {
  406.         case ZPAD:
  407.                 goto splat;
  408.         case RCDO:
  409.         case TIMEOUT:
  410.                 goto fifi;
  411.         default:
  412.                 goto agn2;
  413.         case ZDLE:              /* This is what we want. */
  414.                 break;
  415.         }
  416.  
  417.         switch (c = noxrd7()) {
  418.         case RCDO:
  419.         case TIMEOUT:
  420.                 goto fifi;
  421.         case ZBIN:
  422.                 Rxframeind = ZBIN;  Crc32 = FALSE;
  423.                 c =  zrbhdr(hdr);
  424.                 break;
  425.         case ZBIN32:
  426.                 Crc32 = Rxframeind = ZBIN32;
  427.                 c =  zrbhdr32(hdr);
  428.                 break;
  429.         case ZHEX:
  430.                 Rxframeind = ZHEX;  Crc32 = FALSE;
  431.                 c =  zrhhdr(hdr);
  432.                 break;
  433.         case CAN:
  434.                 goto gotcan;
  435.         default:
  436.                 goto agn2;
  437.         }
  438.         Rxpos = hdr[ZP3] & 0377;
  439.         Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377);
  440.         Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377);
  441.         Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);
  442. fifi:
  443.         switch (c) {
  444.         case GOTCAN:
  445.                 c = ZCAN;
  446.         /* **** FALL THRU TO **** */
  447.         case ZNAK:
  448.         case ZCAN:
  449.         case ERROR:
  450.         case TIMEOUT:
  451.         case RCDO:
  452.                 zperr("Got %s", frametypes[c+FTOFFSET]);
  453.         /* **** FALL THRU TO **** */
  454.         default:
  455.                 if (c >= -3 && c <= FRTYPES)
  456.                         vfile("zgethdr: %s %lx", frametypes[c+FTOFFSET], Rxpos);
  457.                 else
  458.                         vfile("zgethdr: %d %lx", c, Rxpos);
  459.         }
  460.         return c;
  461. }
  462.  
  463. /* Receive a binary style header (type and position) */
  464. int zrbhdr(hdr)
  465. register char *hdr;
  466. {
  467.         register int c, n;
  468.         register unsigned short crc;
  469.  
  470.         if ((c = zdlread()) & ~0377)
  471.                 return c;
  472.         Rxtype = c;
  473.         crc = updcrc(c, 0);
  474.  
  475.         for (n=4; --n >= 0; ++hdr) {
  476.                 if ((c = zdlread()) & ~0377)
  477.                         return c;
  478.                 crc = updcrc(c, crc);
  479.                 *hdr = c;
  480.         }
  481.         if ((c = zdlread()) & ~0377)
  482.                 return c;
  483.         crc = updcrc(c, crc);
  484.         if ((c = zdlread()) & ~0377)
  485.                 return c;
  486.         crc = updcrc(c, crc);
  487.         if (crc & 0xFFFF) {
  488.                 zperr(badcrc);
  489.                 return ERROR;
  490.         }
  491. #ifdef ZMODEM
  492.         Protocol = ZMODEM;
  493. #endif
  494.         Zmodem = 1;
  495.         return Rxtype;
  496. }
  497.  
  498. /* Receive a binary style header (type and position) with 32 bit FCS */
  499. int zrbhdr32(hdr)
  500. register char *hdr;
  501. {
  502.         register int c, n;
  503.         register UNSL long crc;
  504.  
  505.         if ((c = zdlread()) & ~0377)
  506.                 return c;
  507.         Rxtype = c;
  508.         crc = 0xFFFFFFFFL; crc = UPDC32(c, crc);
  509. #ifdef DEBUGZ
  510.         vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  511. #endif
  512.  
  513.         for (n=4; --n >= 0; ++hdr) {
  514.                 if ((c = zdlread()) & ~0377)
  515.                         return c;
  516.                 crc = UPDC32(c, crc);
  517.                 *hdr = c;
  518. #ifdef DEBUGZ
  519.                 vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  520. #endif
  521.         }
  522.         for (n=4; --n >= 0;) {
  523.                 if ((c = zdlread()) & ~0377)
  524.                         return c;
  525.                 crc = UPDC32(c, crc);
  526. #ifdef DEBUGZ
  527.                 vfile("zrbhdr32 c=%X  crc=%lX", c, crc);
  528. #endif
  529.         }
  530.         if (crc != 0xDEBB20E3) {
  531.                 zperr(badcrc);
  532.                 return ERROR;
  533.         }
  534. #ifdef ZMODEM
  535.         Protocol = ZMODEM;
  536. #endif
  537.         Zmodem = 1;
  538.         return Rxtype;
  539. }
  540.  
  541.  
  542. /* Receive a hex style header (type and position) */
  543. int zrhhdr(hdr)
  544. char *hdr;
  545. {
  546.         register int c;
  547.         register unsigned short crc;
  548.         register int n;
  549.  
  550.         if ((c = zgethex()) < 0)
  551.                 return c;
  552.         Rxtype = c;
  553.         crc = updcrc(c, 0);
  554.  
  555.         for (n=4; --n >= 0; ++hdr) {
  556.                 if ((c = zgethex()) < 0)
  557.                         return c;
  558.                 crc = updcrc(c, crc);
  559.                 *hdr = c;
  560.         }
  561.         if ((c = zgethex()) < 0)
  562.                 return c;
  563.         crc = updcrc(c, crc);
  564.         if ((c = zgethex()) < 0)
  565.                 return c;
  566.         crc = updcrc(c, crc);
  567.         if (crc & 0xFFFF) {
  568.                 zperr(badcrc); return ERROR;
  569.         }
  570.         switch ( c = readline(1)) {
  571.         case 0215:
  572.                 Not8bit = c;
  573.                 /* **** FALL THRU TO **** */
  574.         case 015:
  575.                 /* Throw away possible cr/lf */
  576.                 switch (c = readline(1)) {
  577.                 case 012:
  578.                         Not8bit |= c;
  579.                 }
  580.         }
  581. #ifdef ZMODEM
  582.         Protocol = ZMODEM;
  583. #endif
  584.         Zmodem = 1; return Rxtype;
  585. }
  586.  
  587. /* Send a byte as two hex digits */
  588. void zputhex(c)
  589. register int c;
  590. {
  591.         static char     digits[]        = "0123456789abcdef";
  592.  
  593.         if (Verbose>8)
  594.                 vfile("zputhex: %02X", c);
  595.         sendline(digits[(c&0xF0)>>4]);
  596.         sendline(digits[(c)&0xF]);
  597. }
  598.  
  599. /*
  600.  * Send character c with ZMODEM escape sequence encoding.
  601.  *  Escape XON, XOFF. Escape CR following @ (Telenet net escape)
  602.  */
  603. void zsendline(c)
  604. int c;
  605. {
  606.  
  607.         /* Quick check for non control characters */
  608.         if (c & 0140)
  609.                 xsendline(lastsent = c);
  610.         else {
  611.                 switch (c &= 0377) {
  612.                 case ZDLE:
  613.                         xsendline(ZDLE);
  614.                         xsendline (lastsent = (c ^= 0100));
  615.                         break;
  616.                 case 015:
  617.                 case 0215:
  618.                         if (!Zctlesc && (lastsent & 0177) != '@')
  619.                                 goto sendit;
  620.                 /* **** FALL THRU TO **** */
  621.                 case 020:
  622.                 case 021:
  623.                 case 023:
  624.                 case 0220:
  625.                 case 0221:
  626.                 case 0223:
  627.                         xsendline(ZDLE);
  628.                         c ^= 0100;
  629.         sendit:
  630.                         xsendline(lastsent = c);
  631.                         break;
  632.                 default:
  633.                         if (Zctlesc && ! (c & 0140)) {
  634.                                 xsendline(ZDLE);
  635.                                 c ^= 0100;
  636.                         }
  637.                         xsendline(lastsent = c);
  638.                 }
  639.         }
  640. }
  641.  
  642. /* Decode two lower case hex digits into an 8 bit byte value */
  643. int zgethex()
  644. {
  645.         register int c;
  646.  
  647.         c = zgeth1();
  648.         if (Verbose>8)
  649.                 vfile("zgethex: %02X", c);
  650.         return c;
  651. }
  652. int zgeth1()
  653. {
  654.         register int c, n;
  655.  
  656.         if ((c = noxrd7()) < 0)
  657.                 return c;
  658.         n = c - '0';
  659.         if (n > 9)
  660.                 n -= ('a' - ':');
  661.         if (n & ~0xF)
  662.                 return ERROR;
  663.         if ((c = noxrd7()) < 0)
  664.                 return c;
  665.         c -= '0';
  666.         if (c > 9)
  667.                 c -= ('a' - ':');
  668.         if (c & ~0xF)
  669.                 return ERROR;
  670.         c += (n<<4);
  671.         return c;
  672. }
  673.  
  674. /*
  675.  * Read a byte, checking for ZMODEM escape encoding
  676.  *  including CAN*5 which represents a quick abort
  677.  */
  678. int zdlread()
  679. {
  680.         register int c;
  681.  
  682. again:
  683.         /* Quick check for non control characters */
  684.         if ((c = readline(Rxtimeout)) & 0140)
  685.                 return c;
  686.         switch (c) {
  687.         case ZDLE:
  688.                 break;
  689.         case 023:
  690.         case 0223:
  691.         case 021:
  692.         case 0221:
  693.                 goto again;
  694.         default:
  695.                 if (Zctlesc && !(c & 0140)) {
  696.                         goto again;
  697.                 }
  698.                 return c;
  699.         }
  700. again2:
  701.         if ((c = readline(Rxtimeout)) < 0)
  702.                 return c;
  703.         if (c == CAN && (c = readline(Rxtimeout)) < 0)
  704.                 return c;
  705.         if (c == CAN && (c = readline(Rxtimeout)) < 0)
  706.                 return c;
  707.         if (c == CAN && (c = readline(Rxtimeout)) < 0)
  708.                 return c;
  709.         switch (c) {
  710.         case CAN:
  711.                 return GOTCAN;
  712.         case ZCRCE:
  713.         case ZCRCG:
  714.         case ZCRCQ:
  715.         case ZCRCW:
  716.                 return (c | GOTOR);
  717.         case ZRUB0:
  718.                 return 0177;
  719.         case ZRUB1:
  720.                 return 0377;
  721.         case 023:
  722.         case 0223:
  723.         case 021:
  724.         case 0221:
  725.                 goto again2;
  726.         default:
  727.                 if (Zctlesc && ! (c & 0140)) {
  728.                         goto again2;
  729.                 }
  730.                 if ((c & 0140) ==  0100)
  731.                         return (c ^ 0100);
  732.                 break;
  733.         }
  734.         if (Verbose>1)
  735.                 zperr("Bad escape sequence %x", c);
  736.         return ERROR;
  737. }
  738.  
  739. /*
  740.  * Read a character from the modem line with timeout.
  741.  *  Eat parity, XON and XOFF characters.
  742.  */
  743. int noxrd7()
  744. {
  745.         register int c;
  746.  
  747.         for (;;) {
  748.                 if ((c = readline(Rxtimeout)) < 0)
  749.                         return c;
  750.                 switch (c &= 0177) {
  751.                 case XON:
  752.                 case XOFF:
  753.                         continue;
  754.                 default:
  755.                         if (Zctlesc && !(c & 0140))
  756.                                 continue;
  757.                 case '\r':
  758.                 case '\n':
  759.                 case ZDLE:
  760.                         return c;
  761.                 }
  762.         }
  763. }
  764.  
  765. /* Store long integer pos in Txhdr */
  766. void stohdr(pos)
  767. long pos;
  768. {
  769.         Txhdr[ZP0] = pos;
  770.         Txhdr[ZP1] = pos>>8;
  771.         Txhdr[ZP2] = pos>>16;
  772.         Txhdr[ZP3] = pos>>24;
  773. }
  774.  
  775. /* Recover a long integer from a header */
  776. long
  777. rclhdr(hdr)
  778. register char *hdr;
  779. {
  780.         register long l;
  781.  
  782.         l = (hdr[ZP3] & 0377);
  783.         l = (l << 8) | (hdr[ZP2] & 0377);
  784.         l = (l << 8) | (hdr[ZP1] & 0377);
  785.         l = (l << 8) | (hdr[ZP0] & 0377);
  786.         return l;
  787. }
  788.  
  789. /* End of zm.c */

Raw Paste


Login or Register to edit or fork this paste. It's free.