home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: DFÜ und Kommunikation / SOS-DFUE.ISO / programm / dos / utility / pccp076 / xmcrcr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-19  |  5.0 KB  |  275 lines

  1. /*    Copyright (C) 1992,1993 Peter Edward Cann, all rights reserved.
  2.  */
  3.  
  4. #include<stdio.h>
  5. #include<bios.h>
  6. #include<dos.h>
  7. #include<fcntl.h>
  8. #include<sys\types.h>
  9. #include<sys\stat.h>
  10. #include<signal.h>
  11. #include"port.h"
  12.  
  13. #define NAK 21
  14. #define ACK 6
  15. #define SOH 1
  16. #define STX 2
  17. #define HI6 0xb6 /* 0x80 + '6'; the dreaded 16k packet introducer */
  18. #define EOT 4
  19. #define CAN 24
  20.  
  21. unsigned long tick;
  22.  
  23. void (interrupt far *oldtick)();
  24.  
  25. void interrupt far tickhndl()
  26.     {
  27.     tick++;
  28.     }
  29.  
  30. sendchar(c)
  31.     unsigned char c;
  32.     {
  33.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  34.         if(_bios_keybrd(_KEYBRD_READY))
  35.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  36.                 quit();
  37.     outp(basereg, c);
  38.     }
  39.  
  40. int follow;
  41.  
  42. int rcharto(ticks)
  43.     int ticks;
  44.     {
  45.     int c;
  46.     tick=0L;
  47.     while(1)
  48.         {
  49.         if(_bios_keybrd(_KEYBRD_READY))
  50.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  51.                 quit();
  52.         if(tick>ticks)
  53.             return(-1); /* NOTE: This is an INT!!! */
  54.         if(follow!=index)
  55.             {
  56.             c=buf[follow++];
  57.             if(follow>=TBUFSIZ)
  58.                 follow=0;
  59.             return(c);
  60.             }
  61.         }
  62.     }
  63.  
  64. int calccrc(ptr, count)
  65.     char *ptr;
  66.     int count;
  67.     {
  68.     int crc, i;
  69.     crc = 0;
  70.     while(--count >= 0)
  71.         {
  72.         crc = crc ^ (int)*ptr++ << 8;
  73.         for(i = 0; i < 8; ++i)
  74.             if(crc & 0x8000)
  75.                 crc = crc << 1 ^ 0x1021;
  76.             else
  77.                 crc = crc << 1;
  78.         }
  79.     return (crc & 0xFFFF);
  80.     }
  81.  
  82. unsigned char block[16384];
  83.  
  84. rblock(size)
  85. int size;
  86.     {
  87.     unsigned long crc;
  88.     unsigned long rcrc;
  89.     int c, i, j, blockn, invblockn;
  90.     crc=0;
  91.     if((blockn=rcharto(20))==-1)
  92.         return(-1);
  93.     printf("Block %d: ", blockn);
  94.     if((invblockn=rcharto(20))==-1)
  95.         return(-1);
  96.     for(i=0;i<size;++i)
  97.         if((c=rcharto(60))==-1)
  98.             {
  99.             printf("Timeout in data phase after %d bytes.", i);
  100.             return(-1);
  101.             }
  102.         else
  103.             block[i]=c;
  104.     if((c=rcharto(20))==-1)
  105.         {
  106.         printf("Timeout waiting for CRC MSB.\n");
  107.         return(-1);
  108.         }
  109.     rcrc=c<<8;
  110.     if((c=rcharto(20))==-1)
  111.         {
  112.         printf("Timeout waiting for CRC LSB.\n");
  113.         return(-1);
  114.         }
  115.     rcrc|=c;
  116.     crc=calccrc(block, size);
  117.     if(((invblockn^0xff)&0xff)!=blockn)
  118.         {
  119.         printf("Bad complement block number.\n");
  120.         return(-1);
  121.         }
  122.     if(crc!=rcrc)
  123.         {
  124.         printf("CRC mismatch. Here=%04x There=%04x\n", crc, rcrc);
  125.         return(-1);
  126.         }
  127.     return(blockn);
  128.     }
  129.  
  130. quit()
  131.     {
  132.     cleanup(0);
  133.     _dos_setvect(0x1c, oldtick);
  134.     exit(99);
  135.     }
  136.  
  137. main(argc, argv)
  138.     int argc;
  139.     char **argv;
  140.     {
  141.     int i, j, outfd, ok, c;
  142.     unsigned char blocknum;
  143.     long nbytes;
  144.     int bsize;
  145.     index=follow=0;
  146.     printf("Copyright (C) 1992,1993 Peter Edward Cann, all rights reserved.\n");
  147.     printf("xmodem crc 128/1k/16k receive of %s.\n", argv[4]);
  148.     if(argc!=5)
  149.         {
  150.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  151.         exit(1);
  152.         }
  153.     if((outfd=open(argv[4], O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
  154.         {
  155.         printf("Error opening file %s.\n", argv[4]);
  156.         exit(2);
  157.         }
  158.     comnum=atoi(argv[1])-1;
  159.     speed=atoi(argv[2]);
  160.     databits='8';
  161.     parity='n';
  162.     stopbits=argv[3][0];
  163.     setport();
  164.     readset();
  165.     oldtick=_dos_getvect(0x1c);
  166.     signal(SIGINT, quit);
  167.     _dos_setvect(0x1c, tickhndl);
  168.     setup();
  169.     ok=nbytes=0;
  170.     for(i=0;i<10;++i)
  171.         {
  172.         sendchar('C');
  173.         c=rcharto(200);
  174.         if(c==SOH)
  175.             {
  176.             bsize=128;
  177.             ok=1;
  178.             break;
  179.             }
  180.         else if(c==STX)
  181.             {
  182.             bsize=1024;
  183.             ok=1;
  184.             break;
  185.             }
  186.         else if(c==HI6)
  187.             {
  188.             bsize=16384;
  189.             ok=1;
  190.             break;
  191.             }
  192.         }
  193.     if(!ok)
  194.         {
  195.         printf("No SOH, STX or HI6 after 10 10-second-spaced Cs.\n");
  196.         cleanup(0);
  197.         _dos_setvect(0x1c, oldtick);
  198.         exit(10);
  199.         }
  200.     blocknum=1;
  201.     for(i=0;i<10;++i)
  202.         {
  203.         printf("\nSeeking block %d: ", blocknum);
  204.         if((c=rblock(bsize))==blocknum)
  205.             {
  206.             i=0;
  207.             if(write(outfd, block, bsize)!=bsize)
  208.                 {
  209.                 printf("Write error.\n");
  210.                 cleanup(0);
  211.                 _dos_setvect(0x1c, oldtick);
  212.                 exit(13);
  213.                 }
  214.             nbytes+=bsize;
  215.             printf("Successful. Bytes so far: %ld", nbytes);
  216.             blocknum=(blocknum+1)&0xff;
  217.             sendchar(ACK);
  218.             }
  219.         else if(c==-1)
  220.             {
  221.             while(rcharto(20)!=-1);
  222.             sendchar(NAK);
  223.             }
  224.         else if(c<blocknum)
  225.             sendchar(ACK);
  226.         else
  227.             {
  228.             printf("\nSender skipped a block; cancelling transfer.\n");
  229.             for(j=0;j<10;++j)
  230.                 sendchar(CAN);
  231.             while(!(inp(basereg+STATREG)&TXSHMTMASK));
  232.             cleanup(0);
  233.             _dos_setvect(0x1c, oldtick);
  234.             exit(14);
  235.             }
  236.         do
  237.             {
  238.             c=rcharto(200);
  239.             if(c==CAN)
  240.                 c=rcharto(200);
  241.             }
  242.         while((c!=SOH)&&(c!=STX)&&(c!=HI6)&&(c!=EOT)&&(c!=CAN)&&(c!=-1));
  243.         if(c==EOT)
  244.             {
  245.             sendchar(ACK);
  246.             printf("\nTransfer successful.\n");
  247.             close(outfd);
  248.             while(!(inp(basereg+STATREG)&TXSHMTMASK));
  249.             cleanup(0);
  250.             _dos_setvect(0x1c, oldtick);
  251.             exit(0);
  252.             }
  253.         if(c==SOH)
  254.             bsize=128;
  255.         else if(c==STX)
  256.             bsize=1024;
  257.         else if(c==HI6)
  258.             bsize=16384;
  259.         else
  260.             {
  261.             if(c==-1)
  262.                 printf("Timeout waiting for SOH, STX, HI6 or EOT.\n");
  263.             else
  264.                 printf("\nReceived two consecutive CANcel codes (^X).\n");
  265.             cleanup(0);
  266.             _dos_setvect(0x1c, oldtick);
  267.             exit(11);
  268.             }
  269.         }
  270.     printf("Retry limit exceeded.\n");
  271.     cleanup(0);
  272.     _dos_setvect(0x1c, oldtick);
  273.     exit(12);
  274.     }
  275.