home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / xmodem / transmit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  2.8 KB  |  165 lines

  1. /*
  2. **    transmit filename
  3. */
  4. # include <curses.h>
  5. # include <file.h>
  6. # include <signal.h>
  7. # include <time.h>
  8.  
  9. # define    SOH    0x1
  10. # define    NAK    0x15
  11. # define    ACK    0x6
  12. # define    EOT    0x4
  13. # define    CANCEL    0x18
  14.  
  15. int flags;
  16. char filename[64];
  17.  
  18. main(argc,argv)
  19. int argc;
  20. char *argv[]; {
  21.  
  22.     int fd;
  23.     register i;
  24.     register char *p;
  25.     char block[132];
  26.     char c;
  27.     int length, pid;
  28.     int seq_num, xsum;
  29.     int retries;
  30.     struct sigvec vec;
  31.     int caught();
  32.  
  33.     flags = argc;
  34.     if (!((argc == 2) || (argc == 3))) {
  35.         printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
  36.         printf("SYNOPSIS: to_pc_x [-t] [-m] filename\n");
  37.         exit(-1);
  38.     }
  39.  
  40.     if (argc == 2) strcpy(filename,argv[1]);  /* don't put in CR's */
  41.     else { 
  42.         switch (argv[1][1]) {
  43.             case 't':
  44.                 printf("Adding carriage returns, wait .......\n");
  45.                 strcpy(filename,ADDCR(argv[2]));
  46.                 printf("DONE\n");
  47.                 break;
  48.             case 'm':
  49.                 printf("Changing lf's to cr's, wait .......\n");
  50.                 strcpy(filename,LF2CR(argv[2]));
  51.                 printf("DONE\n");
  52.                 break;
  53.             default:
  54.                 printf("bad argument `%s'\n",argv[1]);
  55.                 printf("SYNOPSIS: to_pc_x [-t] [-m] filename\n");
  56.                 exit(-1);
  57.         }
  58.     }
  59.  
  60.     if ((fd = open(filename,O_RDONLY,0644)) < 0) {
  61.         perror(filename);
  62.         exit(-1);
  63.     }
  64.  
  65.     initscr();
  66.     raw();            /* set terminal to 8-bit I/O */
  67.     noecho();
  68.  
  69. /*
  70. **    Ignore interrupts from the user.
  71. **    If the user could delete this program the terminal
  72. **    would be left in a undiserable state of mind.
  73. */
  74.     vec.sv_handler = caught;
  75.     vec.sv_mask = vec.sv_onstack = 0;
  76.     sigvec(SIGALRM,&vec,(struct sigvec *)0);
  77.  
  78.     sigsetmask(-1 ^ (1 << (SIGALRM-1)));
  79.  
  80.     SET_TIMER();
  81.  
  82.     for(;;) {          /* wait for NAK */
  83.         read(0,&c,1);    /* if not received in 60 sec's, program terminates */
  84.         if ((c&0x7f) == NAK) break;
  85.     }
  86.  
  87.     DISABLE_TIMER();
  88.  
  89.     seq_num = 1;
  90.     p = &block[3];
  91.     while ( (length = read(fd,p,128)) > 0 ) {
  92.  
  93.         p = block;
  94.         *p++ = SOH;
  95.         *p++ = seq_num;
  96.         *p++ = 255 - seq_num;
  97.  
  98.         p += length;
  99.         for( i = length; i < 128; i++) *p++ = 0;
  100.         xsum = 0;
  101.         for (i = 3; i < 131; i++) xsum += block[i];
  102.         *p = xsum & 0xff;
  103.  
  104.         retries = 0;
  105.         do {
  106.             if (retries) sleep(10);
  107.  
  108.             write(1,block,132);
  109.             SET_TIMER();
  110.             read(0,&c,1);
  111.             DISABLE_TIMER();
  112.  
  113.             if ( (c&0x7f) == CANCEL ) {RESET(); exit(-1);}
  114.             if (retries++ > 10 ) {
  115.                 c = CANCEL;
  116.                 write(1,&c,1);
  117.                 RESET(); exit(-1);
  118.             }
  119.         } while ( (c&0x7f) != ACK );
  120.  
  121.         seq_num = ++seq_num % 256;
  122.         p = &block[3];
  123.             
  124.     }
  125.  
  126.     SET_TIMER();
  127.     do {
  128.         c = EOT;
  129.         write(1,&c,1);
  130.         read(0,&c,1);
  131.     } while ( (c&0x7f) != ACK );
  132.     DISABLE_TIMER();
  133.  
  134.     RESET();
  135. }
  136.  
  137. RESET() {
  138.  
  139.     noraw();
  140.     echo();
  141.     endwin();
  142.     if (flags == 3) unlink(filename);
  143. } /* END */
  144.  
  145. caught() {
  146.     RESET();
  147.     kill(0,SIGKILL);
  148. }
  149.  
  150. SET_TIMER() {
  151.     struct itimerval val;
  152.  
  153.     val.it_value.tv_sec = 60;
  154.     val.it_value.tv_usec = 60 * 1000;
  155.     timerclear(&val.it_interval);
  156.     setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
  157. }
  158.  
  159. DISABLE_TIMER() {
  160.     struct itimerval val;
  161.  
  162.     timerclear(&val.it_value);
  163.     setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
  164. }
  165.