home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / pcomm / part04 / input.c next >
Encoding:
C/C++ Source or Header  |  1988-05-17  |  6.4 KB  |  333 lines

  1. /*
  2.  * The input routines.  These routines are run as a child process to the
  3.  * main pcomm program.
  4.  */
  5.  
  6. #define LPR "/usr/bin/lpr"
  7.  
  8. #define MAX_ROW    64
  9. #define MAX_COL    128
  10.  
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include <setjmp.h>
  14.  
  15. jmp_buf i_jmp;
  16. unsigned char vs[MAX_ROW][MAX_COL+2];
  17. int row, col;
  18.  
  19. /*
  20.  * Read the serial port and write the characters to the screen.  Watch
  21.  * for signals from the parent process to toggle the fancy options.
  22.  * Writes the characters received to a virtual screen buffer.
  23.  */
  24. int
  25. input(fd, add_lf, log, print, max_row, max_col, vs_file, log_file)
  26. int fd, add_lf, log, print, max_row, max_col;
  27. char *vs_file, *log_file;
  28. {
  29.     FILE *logfp, *lprfp, *popen();
  30.     int hold, skip_row, got_sig();
  31.     unsigned char c;
  32.     char lf=10;
  33.     void _exit();
  34.                     /* set the trap for the signals */
  35.     signal(SIGALRM, SIG_IGN);
  36.     signal(SIGUSR1, got_sig);
  37.     signal(SIGUSR2, got_sig);
  38.     signal(SIGINT,  got_sig);
  39.     signal(SIGTERM, got_sig);
  40.                     /* resonable limits */
  41.     if (max_row > MAX_ROW)
  42.         max_row = MAX_ROW;
  43.     if (max_col > MAX_COL)
  44.         max_col = MAX_COL;
  45.                     /* read previous screen */
  46.     if (!access(vs_file, 0)) {
  47.         read_vs(vs_file, max_row, max_col);
  48.         skip_row = 0;
  49.     }
  50.     else 
  51.         skip_row = 1;
  52.  
  53.     hold = 0;
  54.                     /* startup file pointers */
  55.     if (print)
  56.         lprfp = popen(LPR, "w");
  57.  
  58.     if (log && strcmp(log_file, "NOT_DEFINED"))
  59.         logfp = fopen(log_file, "a");
  60.  
  61.     switch(setjmp(i_jmp)) {
  62.         case 0:            /* no signal */
  63.             break;
  64.         case 1:            /* toggle the data logging */
  65.             signal(SIGUSR1, got_sig);
  66.             if (!strcmp(log_file, "NOT_DEFINED")) {
  67.                 log = 0;
  68.                 break;
  69.             }
  70.             log = log ? 0 : 1;
  71.             if (log)
  72.                 logfp = fopen(log_file, "a");
  73.             else
  74.                 fclose(logfp);
  75.             break;
  76.         case 2:            /* toggle the printer */
  77.             signal(SIGUSR2, got_sig);
  78.             print = print ? 0 : 1;
  79.             if (print)
  80.                 lprfp = popen(LPR, "w");
  81.             else {
  82.                 putc(014, lprfp);
  83.                 pclose(lprfp);
  84.             }
  85.             break;
  86.         case 3:            /* suspend the input */
  87.             signal(SIGINT, got_sig);
  88.             hold = hold ? 0 : 1;
  89.             if (hold)
  90.                 write_vs(vs_file, max_row, max_col);
  91.             break;
  92.         case 4:            /* cleanup and go home */
  93.             signal(SIGTERM, got_sig);
  94.             if (log)
  95.                 fclose(logfp);
  96.             if (print) {
  97.                 putc(014, lprfp);
  98.                 pclose(lprfp);
  99.             }
  100.             _exit(0);
  101.             break;
  102.     }
  103.                     /* any signal will awaken pause() */
  104.     if (hold)
  105.         pause();
  106.                     /* clear if vs_path doesn't exist */
  107.     if (access(vs_file, 0))
  108.         clear_vs(max_row, max_col);
  109.     /*
  110.      * The very first screen we see after dialing has the "Connected to..."
  111.      * message at row 0, therefore we start our virtual screen at row 1.
  112.      */
  113.     if (skip_row) {
  114.         skip_row = 0;
  115.         row = 1;
  116.     }
  117.  
  118.     while(1) {
  119.         if (read(fd, (char *) &c, 1) <= 0)
  120.             continue;
  121.                     /* send to logfile */
  122.         if (log) {
  123.             if (c == 015 && add_lf)
  124.                 fwrite(&lf, 1, 1, logfp);
  125.                     /* no carriage returns in logfile */
  126.             if (c != 015)
  127.                 fwrite((char *) &c, 1, 1, logfp);
  128.         }
  129.                     /* send to printer too ? */
  130.         if (print)
  131.             fwrite((char *) &c, 1, 1, lprfp);
  132.  
  133.                     /* put a char in virtual screen */
  134.         putchar_vs(c, add_lf, max_row, max_col);
  135.  
  136.         write(1, (char *) &c, 1);
  137.                     /* add LF to CR ? */
  138.         if (add_lf)
  139.             write(1, &lf, 1);
  140.     }
  141. }
  142.  
  143. /*
  144.  * Figure out which signal we just received, and fix the return code of
  145.  * the setjmp function above to the proper value.
  146.  */
  147.  
  148. int
  149. got_sig(sig)
  150. int sig;
  151. {
  152.     void longjmp();
  153.  
  154.     switch(sig) {
  155.         case SIGUSR1:
  156.             longjmp(i_jmp, 1);
  157.         case SIGUSR2:
  158.             longjmp(i_jmp, 2);
  159.         case SIGINT:
  160.             longjmp(i_jmp, 3);
  161.         case SIGTERM:
  162.             longjmp(i_jmp, 4);
  163.     }
  164. }
  165.  
  166. /*
  167.  * Put a character in the virtual screen.  This routine saves incoming
  168.  * character in a two dimensional buffer designed to mimic the real
  169.  * screen.  CURRENTLY DOES NOT UNDERSTAND ESCAPE SEQUENCES!
  170.  */
  171.  
  172. int
  173. putchar_vs(c, add_lf, max_row, max_col)
  174. unsigned char c;
  175. int add_lf, max_row, max_col;
  176. {
  177.     int tab_stop;
  178.  
  179.     switch(c) {
  180.         case 8:            /* destructive back space */
  181.             col--;
  182.             if (col < 0)
  183.                 col = 0;
  184.             vs[row][col] = ' ';
  185.             break;
  186.         case 9:            /* tab character */
  187.             tab_stop = col + 8 - (col % 8);
  188.                     /* if wrap around */
  189.             if (tab_stop >= max_col) {
  190.                     /* spaces up to eol */
  191.                 for (; col<max_col; col++)
  192.                     vs[row][col] = ' ';
  193.                 row++;
  194.                 if (row >= max_row)
  195.                     scroll_vs(max_row, max_col);
  196.  
  197.                     /* the remainder of the tab */
  198.                 col = tab_stop - max_col;
  199.             }
  200.             else {
  201.                 for (; col<tab_stop; col++)
  202.                     vs[row][col] = ' ';
  203.             }
  204.             break;
  205.         case 13:        /* carriage return */
  206.             col = 0;
  207.             if (!add_lf)
  208.                 break;
  209.             /* fall thru...*/
  210.         case 10:        /* line feed */
  211.             row++;
  212.             if (row >= max_row)
  213.                 scroll_vs(max_row, max_col);
  214.             break;
  215.         default:        /* a normal character */
  216.             vs[row][col] = c;
  217.             col++;
  218.                     /* wrap around */
  219.             if (col >= max_col) {
  220.                 col = 0;
  221.                 row++;
  222.                 if (row >= max_row)
  223.                     scroll_vs(max_row, max_col);
  224.             }
  225.             break;
  226.     }
  227.     return;
  228. }
  229.  
  230. /*
  231.  * Save the virtual screen to a file.
  232.  */
  233.  
  234. int
  235. write_vs(vs_file, max_row, max_col)
  236. char *vs_file;
  237. int max_row, max_col;
  238. {
  239.     FILE *fp;
  240.     int i;
  241.  
  242.     if (!(fp = fopen(vs_file, "w")))
  243.         return(1);
  244.                     /* current x y coordinates */
  245.     fprintf(fp, "%d,%d\n", row, col);
  246.  
  247.     for (i=0; i<max_row; i++) {
  248.         vs[i][max_col] = NULL;
  249.         fprintf(fp, "%s\n", vs[i]);
  250.     }
  251.     fclose(fp);
  252.     return(0);
  253. }
  254.  
  255. /*
  256.  * Get the virtual screen image from the file.  Since input() gets
  257.  * killed from time to time, the vs_path file is the only way to retain
  258.  * the screen image.
  259.  */
  260.  
  261. int
  262. read_vs(vs_file, max_row, max_col)
  263. char *vs_file;
  264. int max_row, max_col;
  265. {
  266.     FILE *fp;
  267.     int i;
  268.     char buf[10];
  269.                 /* in case the fopen fails... */
  270.     row = 0;
  271.     col = 0;
  272.                 /* not guaranteed to exist yet */
  273.     if (!(fp = fopen(vs_file, "r")))
  274.         return(1);
  275.                 /* get the x, y coordinates */
  276.     fgets(buf, 10, fp);
  277.     scanf(buf, "%d,%d\n", &row, &col);
  278.  
  279.                 /* read the file into the vs array */
  280.     for (i=0; i<max_row; i++) {
  281.         fgets((char *) vs[i], MAX_COL+2, fp);
  282.         vs[i][max_col] = NULL;
  283.     }
  284.  
  285.     fclose(fp);
  286.     return(0);
  287. }
  288.  
  289. /*
  290.  * If the user clears the screen with the ^A-C command, the input
  291.  * has to be in sync.  The way it gets notified, is that the vs_path
  292.  * file disappears.
  293.  */
  294.  
  295. int
  296. clear_vs(max_row, max_col)
  297. int max_row, max_col;
  298. {
  299.     int i, j;
  300.  
  301.     for (i=0; i<max_row; i++) {
  302.         vs[i][max_col] = NULL;
  303.         for (j=0; j<max_col; j++)
  304.             vs[i][j] = ' ';
  305.     }
  306.                     /* home the "cursor" */
  307.     row = 0;
  308.     col = 0;
  309.     return(0);
  310. }
  311.  
  312. /*
  313.  * Do a software scroll on the virtual screen.  Does not alter the
  314.  * 'col' variable.
  315.  */
  316.  
  317. int
  318. scroll_vs(max_row, max_col)
  319. int max_row, max_col;
  320. {
  321.     int i, j;
  322.     char *strcpy();
  323.                     /* move 'em up 1 line */
  324.     for (i=0; i<max_row-1; i++)
  325.         strcpy((char *) vs[i], (char *) vs[i+1]);
  326.                     /* clear the bottom line */
  327.     for (j=0; j<max_col; j++)
  328.         vs[max_row-1][j] = ' ';
  329.  
  330.     row = max_row -1;
  331.     return(0);
  332. }
  333.