home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / pcomm-2.0.2 / part03 / x_ascii.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  6.4 KB  |  323 lines

  1. /*
  2.  * Transfer a file using just XON/XOFF flow control.  Currently limited to
  3.  * 7 bit ASCII codes.  (If this causes too much trouble, I'll change it).
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <curses.h>
  8. #include <signal.h>
  9. #include "config.h"
  10. #include "misc.h"
  11. #include "param.h"
  12.  
  13. #ifdef BSD
  14. #include <setjmp.h>
  15. jmp_buf bl_buf;
  16. #endif /* BSD */
  17.  
  18. static void send_ascii(), rcv_ascii(), putc_ascii();
  19. static int bgetc_line(), buf_read();
  20.  
  21. void
  22. xfer_ascii(list, up)
  23. char *list;
  24. int up;
  25. {
  26.     int cr_lf;
  27.     char *file, *strtok();
  28.     void line_set(), st_line();
  29.     void ascii_mode(), term_mode();
  30.     unsigned int sleep();
  31.  
  32.     touchwin(stdscr);
  33.     refresh();
  34.                     /* only one file from list */
  35.     file = strtok(list, " \t");
  36.  
  37.     cr_lf = !strcmp(param->cr_out, "CR/LF");
  38.     ascii_mode(up);
  39.                     /* out of curses mode */
  40.     resetterm();
  41.     term_mode();
  42.     tty_noblock(0, TRUE);
  43.  
  44.     if (up)
  45.         send_ascii(file, cr_lf);
  46.     else
  47.         rcv_ascii(file, cr_lf);
  48.  
  49.     /*
  50.      * Restoring the TTY modes is easier than setting them... The
  51.      * fixterm() and line_set() routines fix most of the damage.
  52.      */
  53.     line_set();
  54.     fixterm();
  55.     tty_noblock(0, FALSE);
  56.  
  57.     beep();
  58.     st_line("xfer complete");
  59.  
  60.     sleep(2);
  61.     return;
  62. }
  63.  
  64. /*
  65.  * Send a file.  The local echo option is independent of the duplex option,
  66.  * and would very rarely be used since the characters are most likely
  67.  * being echoed on the screen anyway.
  68.  */
  69.  
  70. static void
  71. send_ascii(file, cr_lf)
  72. char *file;
  73. int cr_lf;
  74. {
  75.     extern int fd;
  76.     FILE *fp, *uid_fopen();
  77.     int i, j, strip_cr, strip_lf, add_cr, add_lf, expand, local_echo, pace;
  78.     char buf[80], c, last;
  79.     unsigned int sleep();
  80.     void error_win();
  81.                     /* permission already checked */
  82.     if (!(fp = uid_fopen(file, "r"))) {
  83.         sprintf(buf, "\"%s\"", file);
  84.         error_win(0, "Can't open file for read", buf);
  85.         return;
  86.     }
  87.                     /* ASCII transfer options */
  88.     strip_cr = !strcmp(param->cr_up, "STRIP");
  89.     add_lf = !strcmp(param->cr_up, "ADD LF");
  90.     strip_lf = !strcmp(param->lf_up, "STRIP");
  91.     add_cr = !strcmp(param->lf_up, "ADD CR");
  92.     expand = !strcmp(param->expand, "YES");
  93.     local_echo = !strcmp(param->local_echo, "YES");
  94.     pace = !strcmp(param->pace, "YES");
  95.  
  96.     last = 0;
  97.     while ((i = fgetc(fp)) != EOF) {
  98.                     /* any keyboard activity? */
  99.         switch (j = getchar()) {
  100.             case -1:    /* no key was pressed */
  101.                 break;
  102.             case ESC:    /* <ESC> key for abort */
  103.                 fclose(fp);
  104.                 sleep(2);
  105.                 tty_drain(fd);
  106.                 return;
  107.             default:    /* send the char */
  108.                 c = (char) j & 0x7f;
  109.                 putc_ascii(c, local_echo);
  110.                 if (c == '\r' && cr_lf)
  111.                     putc_ascii('\n', local_echo);
  112.                 break;
  113.         }
  114.         c = (char) i & 0x7f;
  115.                     /* expand blank lines */
  116.         if (expand && last == '\n' && c == '\n')
  117.             putc_ascii(' ', local_echo);
  118.         last = c;
  119.  
  120.                     /* CR translations */
  121.         if (c == '\r' && strip_cr)
  122.             continue;
  123.         if (c == '\r' && add_lf) {
  124.             putc_ascii(c, local_echo);
  125.             putc_ascii('\n', local_echo);
  126.             continue;
  127.         }
  128.                     /* LF translations */
  129.         if (c == '\n' && strip_lf)
  130.             continue;
  131.         if (c == '\n' && add_cr)
  132.             putc_ascii('\r', local_echo);
  133.  
  134.         putc_ascii(c, local_echo);
  135.         /*
  136.          * There's really no mechanism for delaying characters
  137.          * going to the output, so we fake it by waiting for
  138.          * each character to clear the I/O buffer.
  139.          */
  140.         if (pace)
  141.             tty_drain(fd);
  142.     }
  143.     fclose(fp);
  144.     sleep(2);
  145.     tty_drain(fd);
  146.     return;
  147. }
  148.  
  149. /* Put a character on the line, echo it too, if required */
  150.  
  151. static void
  152. putc_ascii(c, local_echo)
  153. char c;
  154. int local_echo;
  155. {
  156.     extern int fd;
  157.     void vs_putchar();
  158.  
  159.     write(fd, &c, 1);
  160.     if (local_echo) {
  161.         write(1, &c, 1);
  162.         vs_putchar(c);
  163.     }
  164.     return;
  165. }
  166.  
  167. /*
  168.  * Receive a file.  The timer is used to end the transfer.  This is not
  169.  * that much different from the data logging option.  The use of bgetc_line()
  170.  * and non-blocking input makes it seem like full duplex, but it's not.
  171.  * Be aware that while the timer is active the keyboard is deaf.
  172.  */
  173.  
  174. static void
  175. rcv_ascii(file, cr_lf)
  176. char *file;
  177. int cr_lf;
  178. {
  179.     FILE *fp, *uid_fopen();
  180.     int i, strip_cr, strip_lf, add_cr, add_lf, got_first;
  181.     unsigned int delay;
  182.     char c, buf[80];
  183.     void error_win(), vs_putchar();
  184.                     /* permission already checked */
  185.     if (!(fp = uid_fopen(file, "w"))) {
  186.         sprintf(buf, "\"%s\"", file);
  187.         error_win(0, "Can't open file for write", buf);
  188.         return;
  189.     }
  190.                     /* ASCII transfer options */
  191.     strip_cr = !strcmp(param->cr_dn, "STRIP");
  192.     add_lf = !strcmp(param->cr_dn, "ADD LF");
  193.     strip_lf = !strcmp(param->lf_dn, "STRIP");
  194.     add_cr = !strcmp(param->lf_dn, "ADD CR");
  195.  
  196.     got_first = 0;
  197.     delay = 1;
  198.     /* CONSTCOND */
  199.     while (1) {
  200.                     /* keyboard activity */
  201.         switch (i = getchar()) {
  202.             case -1:    /* no key was pressed */
  203.                 break;
  204.             case ESC:    /* <ESC> key */
  205.                 fclose(fp);
  206.                 return;
  207.             default:    /* send it */
  208.                 c = (unsigned int) i;
  209.                 putc_line((unsigned char) c);
  210.                 if (c == '\r' && cr_lf)
  211.                     putc_line('\n');
  212.                 break;
  213.         }
  214.                     /* read a character */
  215.         if ((i = bgetc_line(delay)) == -1) {
  216.             /*
  217.              * The transfer timeout is not activated until the
  218.              * first character is received.  Until then, it polls
  219.              * the line for one second and loops backs for
  220.              * keyboard input.
  221.              */
  222.             if (got_first) {
  223.                 fclose(fp);
  224.                 return;
  225.             }
  226.             continue;
  227.         }
  228.         got_first = 1;
  229.         delay = param->timer;
  230.         c = i & 0x7f;
  231.                     /* display it on the screen */
  232.         write(1, &c, 1);
  233.         vs_putchar(c);
  234.                     /* CR translations */
  235.         if (c == '\r' && strip_cr)
  236.             continue;
  237.         if (c == '\r' && add_lf) {
  238.             fputc(c, fp);
  239.             fputc('\n', fp);
  240.             continue;
  241.         }
  242.                     /* LF translations */
  243.         if (c == '\n' && strip_lf)
  244.             continue;
  245.         if (c == '\n' && add_cr) {
  246.             fputc('\r', fp);
  247.             fputc(c, fp);
  248.             continue;
  249.         }
  250.         fputc(c, fp);
  251.     }
  252. }
  253.  
  254. /*
  255.  * Get a character from the line (using buffered I/O) with a specified
  256.  * time-out period in seconds.  If the function times-out, it returns a -1.
  257.  */
  258.  
  259. static int bl_flag;
  260. static int bl_force();
  261.  
  262. static int
  263. bgetc_line(sec)
  264. unsigned int sec;
  265. {
  266.     int c;
  267.     unsigned int alarm();
  268.  
  269.     signal(SIGALRM, (SIG_TYPE(*) ()) bl_force);
  270.     bl_flag = 0;
  271.  
  272.     alarm(sec);
  273.  
  274. #ifdef BSD
  275.     if (setjmp(bl_buf))
  276.         return(-1);
  277. #endif /* BSD */
  278.  
  279.     if ((c = buf_read()) < 0) {
  280.         alarm(0);
  281.         return(-1);
  282.     }
  283.     if (bl_flag)
  284.         return(-1);
  285.     alarm(0);
  286.     return(c);
  287. }
  288.  
  289. /* ARGSUSED */
  290. static int
  291. bl_force(dummy)
  292. int dummy;
  293. {
  294. #ifdef BSD
  295.     longjmp(bl_buf, 1);
  296. #else /* BSD */
  297.     signal(SIGALRM, (SIG_TYPE(*) ()) bl_force);
  298.     bl_flag = 1;
  299.     return(0);
  300. #endif /* BSD */
  301. }
  302.  
  303. /*
  304.  * Do a single character buffered read from the serial port.
  305.  */
  306.  
  307. static int
  308. buf_read()
  309. {
  310.     extern int fd;
  311.     static char buf[CLIST_SIZ];
  312.     static char *bufp = buf;
  313.     static int n = 0;
  314.  
  315.     if (n <= 0) {
  316.         n = read(fd, buf, CLIST_SIZ);
  317.         bufp = buf;
  318.     }
  319.     if (--n >= 0)
  320.         return(*bufp++ & 0xff);
  321.     return(-1);
  322. }
  323.