home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: DFÜ und Kommunikation / SOS-DFUE.ISO / programm / dos / utility / pccp076 / xmodemr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-19  |  4.2 KB  |  228 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 EOT 4
  17. #define CAN 24
  18.  
  19. unsigned long tick;
  20.  
  21. void (interrupt far *oldtick)();
  22.  
  23. void interrupt far tickhndl()
  24.     {
  25.     tick++;
  26.     }
  27.  
  28. sendchar(c)
  29.     unsigned char c;
  30.     {
  31.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  32.         if(_bios_keybrd(_KEYBRD_READY))
  33.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  34.                 quit();
  35.     outp(basereg, c);
  36.     }
  37.  
  38. int follow;
  39.  
  40. int rcharto(ticks)
  41.     int ticks;
  42.     {
  43.     int c;
  44.     tick=0L;
  45.     while(1)
  46.         {
  47.         if(_bios_keybrd(_KEYBRD_READY))
  48.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  49.                 quit();
  50.         if(tick>ticks)
  51.             return(-1); /* NOTE: This is an INT!!! */
  52.         if(follow!=index)
  53.             {
  54.             c=buf[follow++];
  55.             if(follow>=TBUFSIZ)
  56.                 follow=0;
  57.             return(c);
  58.             }
  59.         }
  60.     }
  61.  
  62.  
  63. unsigned char block[128];
  64.  
  65. rblock()
  66.     {
  67.     int i, blockn, invblockn, rchecksum, checksum;
  68.     checksum=0;
  69.     if((blockn=rcharto(20))==-1)
  70.         return(-1);
  71.     printf("Block %d: ", blockn);
  72.     if((invblockn=rcharto(20))==-1)
  73.         return(-1);
  74.     for(i=0;i<128;++i)
  75.         {
  76.         if((block[i]=rcharto(20))==-1)
  77.             {
  78.             printf("Timeout in data phase after %d bytes.", i);
  79.             return(-1);
  80.             }
  81.         checksum+=block[i];
  82.         checksum&=0xff;
  83.         }
  84.     if((rchecksum=rcharto(20))==-1)
  85.         {
  86.         printf("Timeout waiting for checksum.\n");
  87.         return(-1);
  88.         }
  89.     if(((invblockn^0xff)&0xff)!=blockn)
  90.         {
  91.         printf("Bad complement block number.\n");
  92.         return(-1);
  93.         }
  94.     if(checksum!=rchecksum)
  95.         {
  96.         printf("Checksum mismatch. Here=%02x There=%02x.\n", checksum, rchecksum);
  97.         return(-1);
  98.         }
  99.     return(blockn);
  100.     }
  101.  
  102. quit()
  103.     {
  104.     cleanup(0);
  105.     _dos_setvect(0x1c, oldtick);
  106.     exit(99);
  107.     }
  108.  
  109. main(argc, argv)
  110.     int argc;
  111.     char **argv;
  112.     {
  113.     int i, j, outfd, ok, c;
  114.     long nbytes;
  115.     unsigned char blocknum;
  116.     index=follow=0;
  117.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  118.     printf("xmodem checksum receive of %s.\n", argv[4]);
  119.     if(argc!=5)
  120.         {
  121.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  122.         exit(1);
  123.         }
  124.     if((outfd=open(argv[4], O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
  125.         {
  126.         printf("Error opening file %s.\n", argv[4]);
  127.         exit(2);
  128.         }
  129.     comnum=atoi(argv[1])-1;
  130.     speed=atoi(argv[2]);
  131.     databits='8';
  132.     parity='n';
  133.     stopbits=argv[3][0];
  134.     setport();
  135.     readset();
  136.     oldtick=_dos_getvect(0x1c);
  137.     signal(SIGINT, quit);
  138.     _dos_setvect(0x1c, tickhndl);
  139.     setup();
  140.     ok=nbytes=0;
  141.     for(i=0;i<10;++i)
  142.         {
  143.         sendchar(NAK);
  144.         c=rcharto(200);
  145.         if(c==SOH)
  146.             {
  147.             ok=1;
  148.             break;
  149.             }
  150.         }
  151.     if(!ok)
  152.         {
  153.         printf("No SOH after 10 10-second-spaced NAKs.\n");
  154.         cleanup(0);
  155.         _dos_setvect(0x1c, oldtick);
  156.         exit(10);
  157.         }
  158.     blocknum=1;
  159.     for(i=0;i<10;++i)
  160.         {
  161.         printf("\nSeeking block %d: ", blocknum);
  162.         if((c=rblock())==blocknum)
  163.             {
  164.             i=0;
  165.             if(write(outfd, block, 128)!=128)
  166.                 {
  167.                 printf("Write error.\n");
  168.                 cleanup(0);
  169.                 _dos_setvect(0x1c, oldtick);
  170.                 exit(13);
  171.                 }
  172.             nbytes+=128;
  173.             printf("Successful. Bytes so far: %ld", nbytes);
  174.             blocknum=(blocknum+1)&0xff;
  175.             sendchar(ACK);
  176.             }
  177.         else
  178.             if(c==-1)
  179.                 {
  180.                 while(rcharto(20)!=-1);
  181.                 sendchar(NAK);
  182.                 }
  183.             else if(c<blocknum)
  184.                 sendchar(ACK);
  185.             else
  186.                 {
  187.                 printf("\nSender skipped a block; cancelling transfer.\n");
  188.                 for(j=0;j<10;++j)
  189.                     sendchar(CAN);
  190.                 while(!(inp(basereg+STATREG)&TXSHMTMASK));
  191.                 cleanup(0);
  192.                 _dos_setvect(0x1c, oldtick);
  193.                 exit(14);
  194.                 }
  195.         do
  196.             {
  197.             c=rcharto(200);
  198.             if(c==CAN)
  199.                 c=rcharto(200);
  200.             }
  201.         while((c!=EOT)&&(c!=SOH)&&(c!=CAN)&&(c!=-1));
  202.         if(c==EOT)
  203.             {
  204.             sendchar(ACK);
  205.             printf("\nTransfer successful.\n");
  206.             close(outfd);
  207.             while(!(inp(basereg+STATREG)&TXSHMTMASK));
  208.             cleanup(0);
  209.             _dos_setvect(0x1c, oldtick);
  210.             exit(0);
  211.             }
  212.         if(c!=SOH)
  213.             {
  214.             if(c==-1)
  215.                 printf("Timeout waiting for SOH or EOT.\n");
  216.             else
  217.                 printf("\nReceived two consecutive CANcel codes (^X).\n");
  218.             cleanup(0);
  219.             _dos_setvect(0x1c, oldtick);
  220.             exit(11);
  221.             }
  222.         }
  223.     printf("Retry limit exceeded.\n");
  224.     cleanup(0);
  225.     _dos_setvect(0x1c, oldvect);
  226.     exit(12);
  227.     }
  228.