home *** CD-ROM | disk | FTP | other *** search
- /*
- * The input routines. These routines are run as a child process to the
- * main pcomm program.
- */
-
- #define LPR "/usr/bin/lpr"
-
- #define MAX_ROW 64
- #define MAX_COL 128
-
- #include <stdio.h>
- #include <signal.h>
- #include <setjmp.h>
-
- jmp_buf i_jmp;
- unsigned char vs[MAX_ROW][MAX_COL+2];
- int row, col;
-
- /*
- * Read the serial port and write the characters to the screen. Watch
- * for signals from the parent process to toggle the fancy options.
- * Writes the characters received to a virtual screen buffer.
- */
- int
- input(fd, add_lf, log, print, max_row, max_col, vs_file, log_file)
- int fd, add_lf, log, print, max_row, max_col;
- char *vs_file, *log_file;
- {
- FILE *logfp, *lprfp, *popen();
- int hold, skip_row, got_sig();
- unsigned char c;
- char lf=10;
- void _exit();
- /* set the trap for the signals */
- signal(SIGALRM, SIG_IGN);
- signal(SIGUSR1, got_sig);
- signal(SIGUSR2, got_sig);
- signal(SIGINT, got_sig);
- signal(SIGTERM, got_sig);
- /* resonable limits */
- if (max_row > MAX_ROW)
- max_row = MAX_ROW;
- if (max_col > MAX_COL)
- max_col = MAX_COL;
- /* read previous screen */
- if (!access(vs_file, 0)) {
- read_vs(vs_file, max_row, max_col);
- skip_row = 0;
- }
- else
- skip_row = 1;
-
- hold = 0;
- /* startup file pointers */
- if (print)
- lprfp = popen(LPR, "w");
-
- if (log && strcmp(log_file, "NOT_DEFINED"))
- logfp = fopen(log_file, "a");
-
- switch(setjmp(i_jmp)) {
- case 0: /* no signal */
- break;
- case 1: /* toggle the data logging */
- signal(SIGUSR1, got_sig);
- if (!strcmp(log_file, "NOT_DEFINED")) {
- log = 0;
- break;
- }
- log = log ? 0 : 1;
- if (log)
- logfp = fopen(log_file, "a");
- else
- fclose(logfp);
- break;
- case 2: /* toggle the printer */
- signal(SIGUSR2, got_sig);
- print = print ? 0 : 1;
- if (print)
- lprfp = popen(LPR, "w");
- else {
- putc(014, lprfp);
- pclose(lprfp);
- }
- break;
- case 3: /* suspend the input */
- signal(SIGINT, got_sig);
- hold = hold ? 0 : 1;
- if (hold)
- write_vs(vs_file, max_row, max_col);
- break;
- case 4: /* cleanup and go home */
- signal(SIGTERM, got_sig);
- if (log)
- fclose(logfp);
- if (print) {
- putc(014, lprfp);
- pclose(lprfp);
- }
- _exit(0);
- break;
- }
- /* any signal will awaken pause() */
- if (hold)
- pause();
- /* clear if vs_path doesn't exist */
- if (access(vs_file, 0))
- clear_vs(max_row, max_col);
- /*
- * The very first screen we see after dialing has the "Connected to..."
- * message at row 0, therefore we start our virtual screen at row 1.
- */
- if (skip_row) {
- skip_row = 0;
- row = 1;
- }
-
- while(1) {
- if (read(fd, (char *) &c, 1) <= 0)
- continue;
- /* send to logfile */
- if (log) {
- if (c == 015 && add_lf)
- fwrite(&lf, 1, 1, logfp);
- /* no carriage returns in logfile */
- if (c != 015)
- fwrite((char *) &c, 1, 1, logfp);
- }
- /* send to printer too ? */
- if (print)
- fwrite((char *) &c, 1, 1, lprfp);
-
- /* put a char in virtual screen */
- putchar_vs(c, add_lf, max_row, max_col);
-
- write(1, (char *) &c, 1);
- /* add LF to CR ? */
- if (add_lf)
- write(1, &lf, 1);
- }
- }
-
- /*
- * Figure out which signal we just received, and fix the return code of
- * the setjmp function above to the proper value.
- */
-
- int
- got_sig(sig)
- int sig;
- {
- void longjmp();
-
- switch(sig) {
- case SIGUSR1:
- longjmp(i_jmp, 1);
- case SIGUSR2:
- longjmp(i_jmp, 2);
- case SIGINT:
- longjmp(i_jmp, 3);
- case SIGTERM:
- longjmp(i_jmp, 4);
- }
- }
-
- /*
- * Put a character in the virtual screen. This routine saves incoming
- * character in a two dimensional buffer designed to mimic the real
- * screen. CURRENTLY DOES NOT UNDERSTAND ESCAPE SEQUENCES!
- */
-
- int
- putchar_vs(c, add_lf, max_row, max_col)
- unsigned char c;
- int add_lf, max_row, max_col;
- {
- int tab_stop;
-
- switch(c) {
- case 8: /* destructive back space */
- col--;
- if (col < 0)
- col = 0;
- vs[row][col] = ' ';
- break;
- case 9: /* tab character */
- tab_stop = col + 8 - (col % 8);
- /* if wrap around */
- if (tab_stop >= max_col) {
- /* spaces up to eol */
- for (; col<max_col; col++)
- vs[row][col] = ' ';
- row++;
- if (row >= max_row)
- scroll_vs(max_row, max_col);
-
- /* the remainder of the tab */
- col = tab_stop - max_col;
- }
- else {
- for (; col<tab_stop; col++)
- vs[row][col] = ' ';
- }
- break;
- case 13: /* carriage return */
- col = 0;
- if (!add_lf)
- break;
- /* fall thru...*/
- case 10: /* line feed */
- row++;
- if (row >= max_row)
- scroll_vs(max_row, max_col);
- break;
- default: /* a normal character */
- vs[row][col] = c;
- col++;
- /* wrap around */
- if (col >= max_col) {
- col = 0;
- row++;
- if (row >= max_row)
- scroll_vs(max_row, max_col);
- }
- break;
- }
- return;
- }
-
- /*
- * Save the virtual screen to a file.
- */
-
- int
- write_vs(vs_file, max_row, max_col)
- char *vs_file;
- int max_row, max_col;
- {
- FILE *fp;
- int i;
-
- if (!(fp = fopen(vs_file, "w")))
- return(1);
- /* current x y coordinates */
- fprintf(fp, "%d,%d\n", row, col);
-
- for (i=0; i<max_row; i++) {
- vs[i][max_col] = NULL;
- fprintf(fp, "%s\n", vs[i]);
- }
- fclose(fp);
- return(0);
- }
-
- /*
- * Get the virtual screen image from the file. Since input() gets
- * killed from time to time, the vs_path file is the only way to retain
- * the screen image.
- */
-
- int
- read_vs(vs_file, max_row, max_col)
- char *vs_file;
- int max_row, max_col;
- {
- FILE *fp;
- int i;
- char buf[10];
- /* in case the fopen fails... */
- row = 0;
- col = 0;
- /* not guaranteed to exist yet */
- if (!(fp = fopen(vs_file, "r")))
- return(1);
- /* get the x, y coordinates */
- fgets(buf, 10, fp);
- scanf(buf, "%d,%d\n", &row, &col);
-
- /* read the file into the vs array */
- for (i=0; i<max_row; i++) {
- fgets((char *) vs[i], MAX_COL+2, fp);
- vs[i][max_col] = NULL;
- }
-
- fclose(fp);
- return(0);
- }
-
- /*
- * If the user clears the screen with the ^A-C command, the input
- * has to be in sync. The way it gets notified, is that the vs_path
- * file disappears.
- */
-
- int
- clear_vs(max_row, max_col)
- int max_row, max_col;
- {
- int i, j;
-
- for (i=0; i<max_row; i++) {
- vs[i][max_col] = NULL;
- for (j=0; j<max_col; j++)
- vs[i][j] = ' ';
- }
- /* home the "cursor" */
- row = 0;
- col = 0;
- return(0);
- }
-
- /*
- * Do a software scroll on the virtual screen. Does not alter the
- * 'col' variable.
- */
-
- int
- scroll_vs(max_row, max_col)
- int max_row, max_col;
- {
- int i, j;
- char *strcpy();
- /* move 'em up 1 line */
- for (i=0; i<max_row-1; i++)
- strcpy((char *) vs[i], (char *) vs[i+1]);
- /* clear the bottom line */
- for (j=0; j<max_col; j++)
- vs[max_row-1][j] = ' ';
-
- row = max_row -1;
- return(0);
- }
-