home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: DFÜ und Kommunikation / SOS-DFUE.ISO / programm / dos / utility / pccp076 / xmodems.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-20  |  4.2 KB  |  238 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. sblock(blockn)
  66.     unsigned char blockn;
  67.     {
  68.     int i;
  69.     unsigned char checksum;
  70.     checksum=0;
  71.     sendchar(SOH);
  72.     sendchar(blockn);
  73.     sendchar((blockn^0xff)&0xff);
  74.     for(i=0;i<128;++i)
  75.         {
  76.         sendchar(block[i]);
  77.         checksum+=block[i];
  78.         }
  79.     sendchar(checksum);
  80.     }
  81.  
  82. quit()
  83.     {
  84.     cleanup(0);
  85.     _dos_setvect(0x1c, oldtick);
  86.     exit(99);
  87.     }
  88.  
  89. main(argc, argv)
  90.     int argc;
  91.     char **argv;
  92.     {
  93.     int i, j, infd, ok, c;
  94.     unsigned char blocknum;
  95.     long nbytes;
  96.     index=follow=0;
  97.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  98.     printf("xmodem checksum send of %s.\n", argv[4]);
  99.     if(argc!=5)
  100.         {
  101.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  102.         exit(1);
  103.         }
  104.     if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
  105.         {
  106.         printf("Error opening file %s.\n", argv[4]);
  107.         exit(2);
  108.         }
  109.     comnum=atoi(argv[1])-1;
  110.     speed=atoi(argv[2]);
  111.     databits='8';
  112.     parity='n';
  113.     stopbits=argv[3][0];
  114.     setport();
  115.     readset();
  116.     oldtick=_dos_getvect(0x1c);
  117.     signal(SIGINT, quit);
  118.     _dos_setvect(0x1c, tickhndl);
  119.     setup();
  120.     nbytes=0;
  121.     for(i=0;;++i)
  122.         {
  123.         if((c=rcharto(100))==CAN)
  124.             {
  125.             c=rcharto(100);
  126.             if(c==CAN)
  127.                 {
  128.                 printf("Received two consecutive CANcel codes (^X).\n");
  129.                 cleanup(0);
  130.                 _dos_setvect(0x1c, oldtick);
  131.                 exit(40);
  132.                 }
  133.             }
  134.         if(c=='C')
  135.             break;
  136.         if(i>=20)
  137.             {
  138.             printf("No C in 20 five-second tries.\n");
  139.             cleanup(0);
  140.             _dos_setvect(0x1c, oldtick);
  141.             exit(10);
  142.             }
  143.         }
  144.     blocknum=1;
  145.     while(1)
  146.         {
  147.         if((j=read(infd, block, 128))==0)
  148.             {
  149.             printf("End of file.\n");
  150.             sendchar(EOT);
  151.             do
  152.                 {
  153.                 c=rcharto(300);
  154.                 if(c==CAN)
  155.                     c=rcharto(300);
  156.                 }
  157.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  158.             if(c==-1)
  159.                 {
  160.                 printf("\nTimeout.\n");
  161.                 cleanup(0);
  162.                 _dos_setvect(0x1c, oldtick);
  163.                 exit(30);
  164.                 }
  165.             else if(c==NAK)
  166.                 {
  167.                 printf("\nEOT NAKed.\n");
  168.                 cleanup(0);
  169.                 _dos_setvect(0x1c, oldtick);
  170.                 exit(13);
  171.                 }
  172.             else if(c==CAN)
  173.                 {
  174.                 printf("\nReceiver sent two CANcel codes (^X).\n");
  175.                 cleanup(0);
  176.                 _dos_setvect(0x1c, oldtick);
  177.                 exit(31);
  178.                 }
  179.             else
  180.                 {
  181.                 printf("\nSuccessful.\n");
  182.                 cleanup(0);
  183.                 _dos_setvect(0x1c, oldtick);
  184.                 exit(0);    
  185.                 }
  186.             }
  187.         for(c=j;c<128;c++)
  188.             block[c]=26;
  189.         i=0;
  190.         do
  191.             {
  192.             printf("\nSending block %d. ", blocknum);
  193.             sblock(blocknum);
  194.             do
  195.                 {
  196.                 c=rcharto(200);
  197.                 printf("%02x ", c);
  198.                 if(c==CAN)
  199.                     {
  200.                     c=rcharto(200);
  201.                     printf("%02x ", c);
  202.                     }
  203.                 }
  204.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  205.             }
  206.         while((c==NAK)&&(i++<10));
  207.         if(c!=ACK)
  208.             if(c==NAK)
  209.                 {
  210.                 printf("\nRetry limit exceeded.\n");
  211.                 cleanup(0);
  212.                 _dos_setvect(0x1c, oldtick);
  213.                 exit(14);
  214.                 }
  215.             else if(c==-1)
  216.                 {
  217.                 printf("\nTimeout.\n");
  218.                 cleanup(0);
  219.                 _dos_setvect(0x1c, oldtick);
  220.                 exit(33);
  221.                 }
  222.             else
  223.                 {
  224.                 printf("\nReceiver sent two CANcel codes (^X).\n");
  225.                 cleanup(0);
  226.                 _dos_setvect(0x1c, oldtick);
  227.                 exit(11);
  228.                 }
  229.         nbytes+=128;
  230.         printf(" Successful. Bytes so far: %ld", nbytes);
  231.         blocknum++;
  232.         }
  233.     printf("Programming error; fell through end; see code.\n");
  234.     cleanup(0);
  235.     _dos_setvect(0x1c, oldtick);
  236.     exit(12);
  237.     }
  238.