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

  1. #
  2. # include <curses.h>
  3. # include <signal.h>
  4. # include <file.h>
  5.  
  6. # define    ST_BLK    33        /* ! */
  7. # define    READY    34        /* " */
  8. # define    OKAY    35        /* # */
  9. # define    NOT_OK    36        /* $ */
  10. # define    CANCEL    37        /* % */
  11. # define    CR    13        /* \r */
  12. # define    pad "    "
  13.  
  14. int seq_num, old, flags;
  15. char buf[95], seq[4], filename[64];
  16.  
  17. main(argc,argv)
  18. int argc;
  19. char *argv[]; {
  20.  
  21.     int fd;
  22.     register i;
  23.     register char *ptr;
  24.     char *ADDCR();
  25.     char c, chunck[45];
  26.     char *MK_SEQ(), *MK_START(), *itos();
  27.     int lim, pid;
  28.     int first = 1;
  29.  
  30.     flags = argc;
  31.     if (!((argc == 2) || (argc == 3))) {
  32.         printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
  33.         printf("SYNOPSIS: to_pc [-t] filename\n");
  34.         exit(-1);
  35.     }
  36.  
  37.     if (argc == 2) strcpy(filename,argv[1]);  /* don't put in CR's */
  38.     else { 
  39.         if (strcmp(argv[1],"-t")) {
  40.             printf("bad argument `%s'\n",argv[1]);
  41.             printf("SYNOPSIS: to_pc [-t] filename\n");
  42.             exit(-1);
  43.         }
  44.         printf("Adding carriage returns, wait .......\n");
  45.         strcpy(filename,ADDCR(argv[2]));
  46.     }
  47.  
  48.     if ((fd = open(filename,O_RDONLY,0644)) < 0) {
  49.         perror(filename);
  50.         exit(-1);
  51.     }
  52.  
  53.     printf("\nPress Alt-F6 to transmit file to PC.\n");
  54.  
  55.     initscr();
  56.     crmode();    /* set terminal to unbuffered I/O */
  57.  
  58. /*
  59. **    Ignore interrupts from the user.
  60. **    If the user could delete this program the terminal
  61. **    would be left in a undiserable state of mind.
  62. */
  63.     sigsetmask( -1 );    /* ignore all signals */
  64.  
  65.     if ((pid = fork()) == 0) {   /* child sends ready prompt */
  66.         sleep(8); i = 0;
  67.         strcpy(buf,"\"\r");
  68.         while (1) {
  69.             write(1, buf, 2);
  70.             sleep(2);
  71.             if ( i++ == 30 ) break;  /* not receiving ready character */
  72.         }
  73.         RESET();         /* restore terminal to normal state */
  74.         kill(0,SIGKILL);    /* kill all processes */
  75.     }
  76.  
  77.     for(;;) {          /* wait for ready character */
  78.         READ(buf);    /* if not received in 68 sec's, program terminates */
  79.         if (buf[0] == OKAY) break;
  80.     }
  81.  
  82.     kill(pid,SIGKILL);  /* received ok response, so kill child */
  83.     wait(0);
  84.  
  85.     seq_num = 0; strcpy(chunck,argv[argc-1]); lim = strlen(chunck);
  86.     do {             /* make 90 character block */
  87.  
  88.         ptr = MK_START();            /* make start of block */
  89.         if (first) {            /* header record */
  90.             strcpy(ptr,"HH");
  91.             strcat(ptr,chunck);
  92.             ptr = lim + &buf[6];
  93.             first = 0;
  94.         } else {
  95.             if (lim < 5) strcat(ptr,"0");
  96.             strcat(ptr,itos( 2 * lim ));
  97.             ptr = &buf[6];
  98.             for (i = 0; i < lim; i++) {
  99.                 c = (chunck[i] & 0xf0) / 16 + '0';
  100.                 *ptr++ = c > '9' ? c + 7 : c;
  101.                 c = (chunck[i] & 0xf) + '0';
  102.                 *ptr++ = c > '9' ? c + 7 : c;
  103.             }
  104.         }
  105.  
  106.         strcat(ptr,MK_SEQ(MK_XSUM(ptr)));
  107.  
  108.         WRITE();
  109.         WAIT(chunck);
  110.         ERR_CHECK(chunck);
  111.  
  112.     } while ( (lim = read(fd,chunck,40)) > 0 );
  113.  
  114.     ptr = MK_START();
  115.     strcat(ptr,"EE");
  116.     ptr = &buf[6];
  117.     strcat(ptr,MK_SEQ(MK_XSUM(ptr)));
  118.     WRITE();
  119.     READ(chunck);
  120.     ERR_CHECK(chunck);
  121.  
  122.     RESET();
  123.  
  124.     close(fd);
  125. }
  126.  
  127. WAIT(s)
  128. char *s; {
  129.     int pid;
  130.     register i;
  131.  
  132.     if ((pid = fork()) == 0) {
  133.         i = 1;
  134.         while (i++ < 10) {
  135.             WRITE();
  136.         }
  137.         sleep(10);
  138.         LEAVE();
  139.         kill(0,SIGKILL);    /* kill all processes */
  140.     }
  141.  
  142.     READ(s);
  143.     kill(pid,SIGKILL);          /* received response, kill child */
  144.     wait(0);
  145. }
  146.  
  147.  
  148. MK_XSUM(s) 
  149. char *s; {
  150.     register xsum;
  151.     register char *ptr;
  152.  
  153.     ptr = s;
  154.     while ( ptr < &buf[86] ) *ptr++ = ' ';   /* pad buffer with blanks */
  155.     xsum = 0; *ptr = '\0'; ptr = buf;
  156.     while ( *ptr )               /* compute check sum */
  157.         xsum = (xsum ^ *ptr++) & 0177;
  158.     return(xsum);
  159. }
  160.  
  161. char *MK_START() {
  162.     register char *ptr;
  163.  
  164.     ptr = buf;
  165.     *ptr = ST_BLK; *(ptr + 1) = '\0';
  166.     seq_num = ++seq_num % 1000;
  167.     strcpy(seq,MK_SEQ(seq_num));
  168.     strcat(ptr,seq);
  169.     return( &buf[4] );       /* return address to record type */
  170. }
  171.  
  172. ERR_CHECK(resp)
  173. char *resp; {
  174.     char ok[6];
  175.     int count = 1;
  176.  
  177.     while (*resp == NOT_OK) {
  178.         if (count++ > 10) {     /* tried 10 times so exit */
  179.             LEAVE(); exit(0);
  180.         }
  181.         WRITE();
  182.         WAIT(resp);
  183.     }
  184.  
  185.     strcpy(ok,"#"); strcat(ok,seq); strcat(ok,"#");
  186.     count = 1;
  187.     while (strncmp(ok,resp,5)) {
  188.         /* used to be a literal control X */
  189.         if (*resp == '\030') { /* user terminated transfer Alt-F6 */
  190.             RESET(); exit(0);
  191.         }
  192.         if (*resp == CANCEL) { /* programs not in synch */
  193.             RESET(); exit(0);
  194.         }  
  195.         if (count++ > 10) {    /* gave up, tried ten times */
  196.             LEAVE(); exit(0);
  197.         }
  198.         WRITE();
  199.         WAIT(resp);
  200.     }
  201. }
  202.  
  203.  
  204. LEAVE() {
  205.     register char *ptr;
  206.  
  207.     ptr = MK_START();
  208.     strcat(ptr,"XX");
  209.     ptr = &buf[6];
  210.     strcat(ptr,MK_SEQ(MK_XSUM(ptr)));
  211.     WRITE();
  212.     RESET();
  213. }
  214.  
  215.  
  216. char *MK_SEQ(i)
  217. int i; {
  218.     char *itos();
  219.     static char s[3];
  220.  
  221.     if ( i < 100 ) strcpy(s,"0");
  222.     else s[0] = '\0';
  223.     if ( i < 10 ) strcat(s,"0");
  224.     strcat(s,itos(i));
  225.     return( s );
  226. }
  227.  
  228. READ(s)
  229. register char *s; {
  230.     
  231.     char c;
  232.     while (read( 0, s++, 1) > 0) {      /* read characters until a CR is read */
  233.         c = *(s-1);
  234.         if ((c == '\n') || (c == CR)) break;
  235.     }
  236.     *s = '\0';
  237. }
  238.  
  239. WRITE() {
  240.  
  241.     buf[89] = CR; buf[90] = '\0';
  242.     write( 1, buf, 90);
  243. }
  244.  
  245. RESET() {
  246.  
  247.     if (flags == 3) unlink(filename);
  248.     endwin();
  249. }
  250.  
  251. char *itos(i1)
  252. int    i1;
  253. {
  254.     register char    *a;
  255.     register int    i;
  256.     static char    buf[10];
  257.  
  258.     i = i1;
  259.     if (i < 0)
  260.         i = -i;
  261.  
  262.     a = &buf[sizeof buf - 1];
  263.     *a-- = '\0';
  264.     do
  265.     {
  266.         *a-- = i % 10 + '0';
  267.         i /= 10;
  268.     } while (i);
  269.     if (i1 < 0)
  270.         *a-- = '-';
  271.  
  272.     a++;
  273.     return (a);
  274. }
  275.