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 / UTILS / S / ZMP-SRC.LZH / ZMXFER3.C < prev    next >
Text File  |  2000-06-30  |  10KB  |  474 lines

  1. /************************* START OF XFER MODULE 3 ***************************/
  2.  
  3. #include "zmp.h"
  4. #include "zmodem.h"
  5.  
  6. #ifdef   AZTEC_C
  7. #include "libc.h"
  8. #else
  9. #include <stdio.h>
  10. #endif
  11.  
  12. #include <setjmp.h>
  13. extern jmp_buf jb_stop;        /* buffer for longjmp */
  14.  
  15. extern char *ltoa();
  16. extern char Myattn[];
  17.  
  18. extern unsigned Txwindow;    /* Control the size of the transmitted window */
  19. extern unsigned Txwspac;          /* Spacing between zcrcq requests */
  20. extern unsigned Txwcnt;          /* Counter used to space ack requests */
  21. extern int Noeofseen;
  22. extern int Totsecs;              /* total number of sectors this file */
  23. extern char *Txbuf;
  24. extern int Filcnt;               /* count of number of files opened */
  25. extern unsigned Rxbuflen;    /* Receiver's max buffer length */
  26. extern int Rxflags;
  27. extern long Bytcnt;
  28. extern long Lastread;              /* Beginning offset of last buffer read */
  29. extern int Lastn;                 /* Count of last buffer read or -1 */
  30. extern int Dontread;              /* Don't read the buffer, it's still there */
  31. extern long Lastsync;              /* Last offset to which we got a ZRPOS */
  32. extern int Beenhereb4;           /* How many times we've been ZRPOS'd same place */
  33. extern int Incnt;              /* count for chars not read from the Cpmbuf */
  34.  
  35. /*
  36.  * Get the receiver's init parameters
  37.  */
  38.  
  39. getzrxinit()
  40. {
  41.     static int n;
  42.  
  43.     for (n=10; --n>=0; ) {
  44.         if (opabort())
  45.             return NERROR;
  46.         switch (zgethdr(Rxhdr, 1)) {
  47.         case ZCHALLENGE:    /* Echo receiver's challenge numbr */
  48.             stohdr(Rxpos);
  49.             zshhdr(ZACK, Txhdr);
  50.             continue;
  51.         case ZCOMMAND:        /* They didn't see out ZRQINIT */
  52.             stohdr(0L);
  53.             zshhdr(ZRQINIT, Txhdr);
  54.             continue;
  55.         case ZRINIT:
  56.             Rxflags = 0377 & Rxhdr[ZF0];
  57.             Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32));
  58.             Zctlesc |= Rxflags & TESCCTL;
  59.             Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8);
  60.             return (sendzsinit());
  61.         case ZCAN:
  62.         case TIMEOUT:
  63.             return NERROR;
  64.         case ZRQINIT:
  65.             if (Rxhdr[ZF0] == ZCOMMAND)
  66.                 continue;
  67.         default:
  68.             zshhdr(ZNAK, Txhdr);
  69.             continue;
  70.         }
  71.     }
  72.     return NERROR;
  73. }
  74.  
  75. /* Send send-init information */
  76.  
  77. sendzsinit()
  78. {
  79.     int tries;
  80.  
  81.     stohdr(0L);        /* All flags are undefined */
  82.     strcpy(Txbuf,Myattn);    /* Copy Attn string */
  83.     for (tries = 0; tries < 20; tries++)
  84.     {
  85.         if (opabort())
  86.             return NERROR;
  87.         zsbhdr(ZSINIT,Txhdr);    /* Send binary header */
  88.         zsdata(Txbuf,strlen(Txbuf) + 1,ZCRCW);    /* Send string */
  89.         if (zgethdr(Rxhdr,0) == ZACK)
  90.             return OK;
  91.         zperr("Bad ACK: ZSINIT",FALSE);
  92.     }
  93.     return NERROR;
  94. }
  95.  
  96. /* Send file name and related info */
  97.  
  98. zsendfile(buf, blen)
  99. char *buf;
  100. int blen;
  101. {
  102.     static int c;
  103.  
  104.     for (;;) {
  105.         if (opabort())
  106.             return NERROR;
  107.         Txhdr[ZF0] = 0;    /* file conversion request */
  108.         Txhdr[ZF1] = 0;    /* file management request */
  109.         Txhdr[ZF2] = 0;    /* file transport request */
  110.         Txhdr[ZF3] = 0;
  111.         zsbhdr(ZFILE, Txhdr);
  112.         zsdata(buf, blen, ZCRCW);
  113. again:
  114.         c = zgethdr(Rxhdr, 1);
  115.         switch (c) {
  116.         case ZRINIT:
  117.             while ((c = readline(INTRATIME)) > 0)
  118.                 if (c == ZPAD) {
  119.                     goto again;
  120.                 }
  121.             /* **** FALL THRU TO **** */
  122.         default:
  123.             continue;
  124.         case ZCAN:
  125.         case TIMEOUT:
  126.         case ZABORT:
  127.         case ZFIN:
  128.             return NERROR;
  129.         case ZSKIP:
  130.             return c;
  131.         case ZRPOS:
  132.             /*
  133.              * Suppress zcrcw request otherwise triggered by
  134.              * lastyunc==Bytcnt
  135.              */
  136.             Lastsync = (Bytcnt = Txpos = Rxpos) -1L;
  137.  
  138. #ifdef AZTEC_C
  139.             fseek(Fd, Rxpos, 0);   /* absolute offset */
  140. #else
  141.             lseek(Fd, Rxpos, 0);   /* absolute offset */
  142. #endif
  143.  
  144.                  clrline(KBYTES);
  145.                Incnt = 0;
  146.                  Dontread = FALSE;
  147.             c = zsndfdata();
  148.             Sending = FALSE;
  149.             return c;
  150.         }
  151.     }
  152. }
  153.  
  154. /* Send the data in the file */
  155.  
  156. zsndfdata()
  157. {
  158.     static int c, e, n;
  159.     static int newcnt;
  160.     static long tcount;
  161.     static int junkcount;      /* Counts garbage chars received by TX */
  162.  
  163.     tcount = 0L;
  164.     Blklen = 128;
  165.     if (Baudrate > 300)
  166.         Blklen = 256;
  167.     if (Baudrate > 1200)
  168.         Blklen = 512;
  169.     if (Baudrate > 2400)
  170.         Blklen = KSIZE;
  171.     if (Rxbuflen && Blklen>Rxbuflen)
  172.         Blklen = Rxbuflen;
  173.     Lrxpos = 0L;
  174.     junkcount = 0;
  175.     Beenhereb4 = FALSE;
  176.     Sending = Firstsec = TRUE;
  177. somemore:
  178.     if (NULL) {
  179. waitack:
  180.         junkcount = 0;
  181.         c = getinsync(0);
  182.         if (QuitFlag)
  183.             return NERROR;
  184. gotack:
  185.         if (setjmp(jb_stop)) {    /* come here if rx stops us */
  186. rxint:
  187.             c = getinsync(1);
  188.         }
  189.  
  190.         switch (c) {
  191.             default:
  192.             case ZCAN:
  193.                 return NERROR;
  194.             case ZSKIP:
  195.                 return c;
  196.             case ZACK:
  197.             case ZRPOS:
  198.                 break;
  199.             case ZRINIT:
  200.                 return OK;
  201.         }
  202.         /*
  203.          * If the reverse channel can be tested for data,
  204.          *  this logic may be used to detect error packets
  205.          *  sent by the receiver, in place of setjmp/longjmp
  206.          *  minprdy() returns non 0 if a character is available
  207.          */
  208.         while (minprdy()) {
  209.             if (QuitFlag)
  210.                 return NERROR;
  211.             switch (readline(1)) {
  212.             case CTRLC:
  213.             case CAN:
  214.             case ZPAD:
  215.                 goto rxint;
  216.             case XOFF:        /* Wait a while for an XON */
  217.             case XOFF|0200:
  218.                 readline(100);
  219.             }
  220.         }
  221.     }
  222.  
  223.     if (setjmp(jb_stop)) {    /* rx interrupt */
  224.         c = getinsync(1);
  225.         if (c == ZACK)
  226.             goto gotanother;
  227.         purgeline();
  228.     /* zcrce - dinna wanna starta ping-pong game */
  229.         zsdata(Txbuf, 0, ZCRCE);
  230.         goto gotack;
  231.     }
  232.  
  233.     newcnt = Rxbuflen;
  234.     Txwcnt = 0;
  235.     stohdr(Txpos);
  236.     zsbhdr(ZDATA, Txhdr);
  237.     do {
  238.         if (QuitFlag)
  239.             return NERROR;
  240.         if (Dontread) {
  241.             n = Lastn;
  242.         } 
  243.         else {
  244.             n = filbuf(Txbuf, Blklen);
  245.             Lastread = Txpos;  
  246.             Lastn = n;
  247.         }
  248.         Dontread = FALSE;
  249.         if (n < Blklen)
  250.             e = ZCRCE;
  251.         else if (junkcount > 3)
  252.             e = ZCRCW;
  253.         else if (Bytcnt == Lastsync)
  254.             e = ZCRCW;
  255.         else if (Rxbuflen && (newcnt -= n) <= 0)
  256.             e = ZCRCW;
  257.         else if (Txwindow && (Txwcnt += n) >= Txwspac) {
  258.             Txwcnt = 0;  
  259.             e = ZCRCQ;
  260.         }
  261.         else
  262.             e = ZCRCG;
  263.         zsdata(Txbuf, n, e);
  264.         Txpos += (long)n;
  265.         Bytcnt = Txpos;
  266.         crcrept(Crc32t);    /* praps report crc mode */
  267.         lreport(KBYTES,Bytcnt);
  268.         if (e == ZCRCW)
  269.             goto waitack;
  270.  
  271.        /*
  272.          * If the reverse channel can be tested for data,
  273.          *  this logic may be used to detect error packets
  274.          *  sent by the receiver, in place of setjmp/longjmp
  275.          *  minprdy() returns non 0 if a character is available
  276.          */
  277.  
  278.         while (minprdy()) {
  279.             if (QuitFlag)
  280.                 return NERROR;
  281.             switch (readline(1)) {
  282.                    case CAN:
  283.                 case CTRLC:
  284.                 case ZPAD:
  285.                     c = getinsync(1);
  286.                     if (c == ZACK)
  287.                         break;
  288.                     purgeline();
  289.         /* zcrce - dinna wanna starta ping-pong game */
  290.                     zsdata(Txbuf, 0, ZCRCE);
  291.                     goto gotack;
  292.                 case XOFF:     /* Wait a while for an XON */
  293.                 case XOFF|0200:
  294.                     readline(100);
  295.                 default:
  296.                     ++junkcount;
  297.  
  298.             }
  299. gotanother:;
  300.         }
  301.         if (Txwindow) {
  302.             while ((tcount = Txpos - Lrxpos) >= Txwindow) {
  303.                 if (QuitFlag)
  304.                     return NERROR;
  305.                 if (e != ZCRCQ)
  306.                     zsdata(Txbuf, 0, e = ZCRCQ);
  307.                 c = getinsync(1);
  308.                 if (c != ZACK) {
  309.                     purgeline();
  310.                     zsdata(Txbuf, 0, ZCRCE);
  311.                     goto gotack;
  312.                 }
  313.             }
  314.         }
  315.     } 
  316.     while (n == Blklen);
  317.  
  318.     for (;;) {
  319.         if (QuitFlag)
  320.             return NERROR;
  321.         stohdr(Txpos);
  322.         zsbhdr(ZEOF, Txhdr);
  323.         switch (getinsync(0)) {
  324.         case ZACK:
  325.             continue;
  326.         case ZRPOS:
  327.             goto somemore;
  328.         case ZRINIT:
  329.             return OK;
  330.         case ZSKIP:
  331.             return c;
  332.         default:
  333.             return NERROR;
  334.         }
  335.     }
  336. }
  337.  
  338. /*
  339.  * Respond to receiver's complaint, get back in sync with receiver
  340.  */
  341.  
  342. getinsync(flag)      /* flag means that there was an error */
  343. int flag;
  344. {
  345.     static int c;
  346.     unsigned u;
  347.  
  348.     for (;;) {
  349.         if (opabort())
  350.             return NERROR;
  351.         c = zgethdr(Rxhdr, 0);
  352.         c = c < FRTYPES ? c : FRTYPES-1;
  353.         sprintf(Buf,"Got %s", frametypes[c+FTOFFSET]);
  354.         zperr(Buf,flag);
  355.         switch (c) {
  356.  
  357.             case ZCAN:
  358.             case ZABORT:
  359.             case ZFIN:
  360.             case TIMEOUT:
  361.                 return NERROR;
  362.  
  363.         case ZRPOS:
  364.             /* ************************************* */
  365.             /*  If sending to a modem beuufer, you   */
  366.             /*   might send a break at this point to */
  367.             /*   dump the modem's buffer.         */
  368.  
  369.             if (Lastn >= 0 && Lastread == Rxpos) {
  370.                 Dontread = TRUE;
  371.             } 
  372.             else {
  373.  
  374. #ifdef AZTEC_C
  375.                    u = fseek(Fd, Rxpos, 0);   /* absolute offset */
  376.                 if (u != EOF)
  377.                     uneof(Fd);    /* Reset EOF flag */
  378. #else
  379.                    u = lseek(Fd, Rxpos, 0);   /* absolute offset */
  380. #endif
  381.  
  382.                         clrline(KBYTES);
  383.                         Incnt = 0;
  384.             }
  385.             Bytcnt = Lrxpos = Txpos = Rxpos;
  386.             if (Lastsync == Rxpos) {
  387.                 if (++Beenhereb4 > 4)
  388.                     if (Blklen > 256)
  389.                         Blklen /= 2;
  390.             }
  391.             Lastsync = Rxpos;
  392.             return c;
  393.  
  394.         case ZACK:
  395.             Lrxpos = Rxpos;
  396.             if (flag || Txpos == Rxpos)
  397.                 return ZACK;
  398.             continue;
  399.  
  400.         case ZRINIT:
  401.         case ZSKIP:
  402.             return c;
  403.  
  404.         case NERROR:
  405.         default:
  406.             zsbhdr(ZNAK, Txhdr);
  407.             continue;
  408.         }
  409.     }
  410. }
  411.  
  412. /* Say "bibi" to the receiver, try to do it cleanly */
  413.  
  414. saybibi()
  415. {
  416.     for (;;) {
  417.         stohdr(0L);        /* CAF Was zsbhdr - minor change */
  418.         zshhdr(ZFIN, Txhdr);    /*  to make debugging easier */
  419.         switch (zgethdr(Rxhdr, 0)) {
  420.         case ZFIN:
  421.             mcharout('O'); 
  422.             mcharout('O'); 
  423.         case ZCAN:
  424.         case TIMEOUT:
  425.             return;
  426.         }
  427.     }
  428. }
  429.  
  430. char *
  431. ttime(fsize)
  432. long fsize;
  433. {
  434.     static int efficiency, cps, seconds;
  435.     static char buffer[10];
  436.  
  437.     efficiency = Zmodem ? 9 : 8;
  438.     cps = (Baudrate/100) * efficiency;   
  439.     seconds = (int)(fsize/cps);     
  440.     sprintf(buffer,"%d:%02d",seconds/60,seconds%60);
  441.     return buffer;
  442. }
  443.  
  444. tfclose()          /* close file if still open */
  445. {
  446. #ifdef AZTEC_C
  447.     if (Fd)
  448.         fclose(Fd);
  449.     Fd = 0;
  450. #else
  451.     if (Fd >= 0)
  452.         close(Fd);
  453.     Fd = -1;
  454. #endif
  455. }
  456.  
  457. #ifdef AZTEC_C
  458. /* Reset EOF flag on a stream (yes, I know this is a kludge! Blame Manx) */
  459. uneof(fp)
  460. register FILE *fp;
  461. {
  462.     fp->_flags &= ~_EOF;
  463. }
  464. #endif
  465.  
  466. slabel() /*print send mode labels on the 25th line*/
  467. {
  468.     sprintf(Buf,"SEND FILE Mode:  Press ESC to Abort...");
  469.     putlabel(Buf);
  470. }
  471.  
  472. /************************** END OF MODULE 7A *********************************/
  473.  
  474.