home *** CD-ROM | disk | FTP | other *** search
- /*
- * The input routines. This program runs as a child process to the
- * Pcomm program.
- */
-
- #define CLIST 64
-
- #include <stdio.h>
- #include <signal.h>
- #include <setjmp.h>
- #include "config.h"
- #ifdef SHAREDMEM
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #endif /* SHAREDMEM */
- #define MAIN
- #include "misc.h"
- #include "status.h"
- #include "vcs.h"
-
- jmp_buf i_jmp;
- int vcs_param[NUM_VCS][5]; /* positional parameters */
- int vcs_opt[NUM_VCS][10]; /* options unique to each vcs */
- int vcs_codes[NUM_VCS][VCS_SIZE]; /* the vcs codes */
- int vcs_leadin[NUM_VCS]; /* unique list of lead-in characters */
- int num_leadin; /* length of lead-in list */
- int hold, max_row, max_col, skip_row;
- FILE *logfp, *lprfp;
- struct STATUS *status;
-
- #ifdef SHAREDMEM
- #define VROW status->row
- #define VCOL status->col
- #define VS status->vs
- #else /* SHAREDMEM */
- int VROW, VCOL;
- char VS[MAX_ROW][MAX_COL+2];
- struct STATUS s;
- #endif /* SHAREDMEM */
-
- /*
- * 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.
- */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- FILE *popen();
- int got_sig();
- char c, *strcpy();
- void _exit(), exit(), vcs_table();
- #ifdef SHAREDMEM
- int shm_id;
- char *shmat();
- #endif /* SHAREDMEM */
- /* set the trap for the signals */
- signal(SIGALRM, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGUSR1, got_sig);
- signal(SIGUSR2, got_sig);
- signal(SIGINT, got_sig);
- signal(SIGTERM, got_sig);
- /* unbuffered output */
- setbuf(stdout, (char *) NULL);
- /* for the curious... */
- if (argc == 1) {
- fprintf(stderr, "This is the input routine for the Pcomm program\n");
- fprintf(stderr, "It is not designed to be run as a separate program\n");
- exit(1);
- }
- #ifdef SHAREDMEM
- shm_id = atoi(argv[1]);
- status = (struct STATUS *) shmat(shm_id, (char *) 0, 0);
- if ((int) status == -1) {
- perror("shmat");
- _exit(1);
- }
- #else /* SHAREDMEM */
- status = &s;
- #endif /* SHAREDMEM */
- /* load the VCS table */
- vcs_table();
- if (max_row > MAX_ROW)
- max_row = MAX_ROW;
- if (max_col > MAX_COL)
- max_col = MAX_COL;
- /* parse the command line */
- #ifndef SHAREDMEM
- status->fd = atoi(argv[1]);
- status->add_lf = atoi(argv[2]);
- status->log = atoi(argv[3]);
- status->print = atoi(argv[4]);
- strcpy(status->log_path, argv[5]);
- strcpy(status->vs_path, argv[6]);
- #endif /* SHAREDMEM */
-
- skip_row = 0;
- #ifdef SHAREDMEM
- if (status->clr)
- skip_row = 1;
- #else /* SHAREDMEM */
- /* read previous screen */
- if (!access(status->vs_path, 0))
- read_vs();
- else
- skip_row = 1;
- #endif /* SHAREDMEM */
-
- hold = 0;
- /* start up file pointers */
- lprfp = (FILE *) NULL;
- logfp = (FILE *) NULL;
-
- switch (setjmp(i_jmp)) {
- case 0: /* no signal */
- break;
- case 1: /* toggle the data logging */
- status->log = status->log ? 0 : 1;
- break;
- case 2: /* toggle the printer */
- status->print = status->print ? 0 : 1;
- break;
- case 3: /* suspend the input */
- hold = hold ? 0 : 1;
- #ifndef SHAREDMEM
- if (hold)
- write_vs();
- #endif /* SHAREDMEM */
- break;
- case 4: /* clean up and go home */
- if (status->log)
- fclose(logfp);
- if (status->print) {
- putc('\f', lprfp);
- pclose(lprfp);
- }
- #ifdef SHAREDMEM
- /* detach shared memory */
- shmdt((char *) status);
- #endif /* SHAREDMEM */
- _exit(0);
- break;
- }
- /* any signal will awaken pause() */
- if (hold)
- pause();
- /* open or close the printer */
- if (status->print && lprfp == NULL)
- lprfp = popen(LPR, "w");
-
- if (!status->print && lprfp != NULL) {
- putc('\f', lprfp);
- pclose(lprfp);
- lprfp = (FILE *) NULL;
- }
- /* open or close the log file */
- if (status->log && logfp == NULL) {
- if (strcmp(status->log_path, "NOT_DEFINED")) {
- if (!(logfp = fopen(status->log_path, "a")))
- status->log = 0;
- }
- else
- status->log = 0;
- }
- if (!status->log && logfp != NULL) {
- fclose(logfp);
- logfp = (FILE *) NULL;
- }
-
- #ifdef SHAREDMEM
- if (status->clr) {
- status->clr = 0;
- vs_clear();
- }
- #else /* SHAREDMEM */
- /* clear if vs_path doesn't exist */
- if (access(status->vs_path, 0))
- vs_clear();
- #endif /* SHAREDMEM */
- /*
- * 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;
- VROW = 1;
- }
-
- while (1) {
- if ((int) (c = readbyte()) <= 0)
- continue;
- /* send to logfile */
- if (status->log) {
- if (c == '\r' && status->add_lf)
- putc('\n', logfp);
- /* no carriage returns in logfile */
- if (c != '\r')
- putc(c, logfp);
- }
- /* send to printer too? */
- if (status->print)
- putc(c, lprfp);
-
- /* put a char in virtual screen */
- vs_putchar(c);
-
- putchar(c);
- /* add LF to CR? */
- if (c == '\r' && status->add_lf)
- putchar('\n');
- }
- }
-
- /*
- * 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:
- signal(SIGUSR1, got_sig);
- longjmp(i_jmp, 1);
- case SIGUSR2:
- signal(SIGUSR2, got_sig);
- longjmp(i_jmp, 2);
- case SIGINT:
- signal(SIGINT, got_sig);
- longjmp(i_jmp, 3);
- case SIGTERM:
- signal(SIGTERM, got_sig);
- longjmp(i_jmp, 4);
- }
- }
-
- /*
- * Put a character in the virtual screen. This routine saves incoming
- * characters in a two dimensional buffer designed to mimic the real
- * screen.
- */
-
- int
- vs_putchar(c)
- char c;
- {
- register int j, i;
- int tab_stop;
-
- switch (vcs_filter(c)) {
- case MAYBE: /* wait and see... */
- break;
- case 256+HOME: /* home virtual screen "cursor" */
- VROW = 0;
- VCOL = 0;
- break;
- case 256+CLR_EOL: /* clear to end of line */
- for (i=VCOL; i<max_col; i++)
- VS[VROW][i] = ' ';
- break;
- case 256+CLR_EOS: /* clear to end of screen */
- for (j=VCOL; j<max_col; j++)
- VS[VROW][j] = ' ';
- for (i=VROW+1; i<max_row; i++) {
- for (j=0; j<max_col; j++)
- VS[i][j] = ' ';
- }
- break;
- case 256+CLEAR: /* clear all and home "cursor" */
- for (i=0; i<max_row; i++) {
- for (j=0; j<max_col; j++)
- VS[i][j] = ' ';
- }
- VROW = 0;
- VCOL = 0;
- break;
- case 256+MV_UP: /* move "cursor" up */
- VROW--;
- if (VROW < 0)
- VROW = 0;
- break;
- case 256+MV_DOWN: /* move "cursor" down */
- VROW++;
- if (VROW >= max_row)
- VROW = max_row -1;
- break;
- case 256+MV_RIGHT: /* move "cursor" right */
- VCOL++;
- if (VCOL >= max_col)
- VCOL = max_col -1;
- break;
- case 256+MV_LEFT: /* move "cursor" left */
- case BS: /* non destructive back space */
- VCOL--;
- if (VCOL < 0)
- VCOL = 0;
- break;
- case 256+MV_DIRECT: /* direct cursor movement */
- VROW = vcs_param[MV_DIRECT][0];
- VCOL = vcs_param[MV_DIRECT][1];
-
- /* if "add one" and "decimal" */
- if (vcs_opt[MV_DIRECT][0] && vcs_opt[MV_DIRECT][1]) {
- VROW--;
- VCOL--;
- }
- /* if "character" */
- if (vcs_opt[MV_DIRECT][2]) {
- /* if "add offset" */
- if (vcs_opt[MV_DIRECT][3]) {
- VROW -= vcs_opt[MV_DIRECT][5];
- VCOL -= vcs_opt[MV_DIRECT][5];
- }
- /* if "subtract offset" */
- if (vcs_opt[MV_DIRECT][4]) {
- VROW += vcs_opt[MV_DIRECT][5];
- VCOL += vcs_opt[MV_DIRECT][5];
- }
- VROW--;
- VCOL--;
- }
- break;
- case '\t': /* tab character */
- tab_stop = VCOL + 8 - (VCOL % 8);
- /* if wrap around */
- if (tab_stop >= max_col) {
- /* spaces up to eol */
- for (; VCOL<max_col; VCOL++)
- VS[VROW][VCOL] = ' ';
- VROW++;
- if (VROW >= max_row)
- vs_scroll();
-
- /* the remainder of the tab */
- VCOL = tab_stop - max_col;
- }
- else {
- for (; VCOL<tab_stop; VCOL++)
- VS[VROW][VCOL] = ' ';
- }
- break;
- case '\r': /* carriage return */
- VCOL = 0;
- if (!status->add_lf)
- break;
- /* fall thru...*/
- case '\n': /* line feed */
- VROW++;
- if (VROW >= max_row)
- vs_scroll();
- break;
- default: /* a normal character */
- VS[VROW][VCOL] = c;
- VCOL++;
- /* wrap around */
- if (VCOL >= max_col) {
- VCOL = 0;
- VROW++;
- if (VROW >= max_row)
- vs_scroll();
- }
- break;
- }
- return(0);
- }
-
- #ifndef SHAREDMEM
- /*
- * Save the virtual screen to a file.
- */
-
- int
- write_vs()
- {
- FILE *fp;
- register int i;
-
- if (!(fp = fopen(status->vs_path, "w")))
- return(1);
- /* current x y coordinates */
- fprintf(fp, "%d,%d\n", VROW, VCOL);
-
- 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()
- {
- FILE *fp;
- register int i;
- char buf[10];
- /* in case the fopen fails... */
- VROW = 0;
- VCOL = 0;
- /* not guaranteed to exist yet */
- if (!(fp = fopen(status->vs_path, "r")))
- return(1);
- /* get the x, y coordinates */
- fgets(buf, 10, fp);
- scanf(buf, "%d,%d\n", VROW, VCOL);
-
- /* read the file into the vs array */
- for (i=0; i<max_row; i++) {
- fgets(VS[i], MAX_COL+2, fp);
- VS[i][max_col] = NULL;
- }
- fclose(fp);
- return(0);
- }
- #endif /* SHAREDMEM */
-
- /*
- * If the user clears the screen with the ^A-C command, the input
- * has to be in sync.
- */
-
- int
- vs_clear()
- {
- register int j, i;
-
- 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" */
- VROW = 0;
- VCOL = 0;
- return(0);
- }
-
- /*
- * Do a software scroll on the virtual screen. Does not alter the
- * "col" variable.
- */
-
- int
- vs_scroll()
- {
- register int i;
- char *strcpy();
- /* move 'em up 1 line */
- for (i=0; i<max_row-1; i++)
- strcpy(VS[i], VS[i+1]);
- /* clear the bottom line */
- for (i=0; i<max_col; i++)
- VS[max_row-1][i] = ' ';
-
- VROW = max_row -1;
- return(0);
- }
-
- /*
- * Do a buffered read from the serial port.
- */
-
- int
- readbyte()
- {
- static char buf[CLIST];
- static char *bufp = buf;
- static int n = 0;
-
- if (n <= 0) {
- if ((n = read(status->fd, buf, CLIST)) <= 0)
- return(-1);
- bufp = buf;
- }
- while (--n >= 0)
- return(*bufp++ & 0xff);
- return(-1);
- }
-