home *** CD-ROM | disk | FTP | other *** search
- /*
- * Start the terminal dialogue, fork the input routine, watch for the
- * hot key so we can execute an option.
- */
-
- #include <stdio.h>
- #include <curses.h>
- #include <signal.h>
- #ifdef UNIXPC
- #include <sys/phone.h>
- #include <fcntl.h>
- #endif /* UNIXPC */
- #include "dial_dir.h"
- #include "modem.h"
- #include "param.h"
- #include "status.h"
-
- terminal(input_status)
- int input_status;
- {
- int i, k, cr_lf;
- char c, lf=10, *strdup(), *new_dir, *change_dir();
- void help_screen(), line_set(), native_shell(), load_vs();
- void setup_menu(), hang_up(), input_on(), list_dir(), pexit();
- void status_line(), free_ptr(), screen_dump(), input_off();
-
- /* if starting out in command mode */
- if (!input_status)
- status_line(NULL);
- /* put the terminal in raw mode */
- resetterm();
- cr_lf = raw_mode();
-
- if (input_status)
- input_on();
-
- while(1) {
- read(0, &c, 1);
- /* is it the hot key? */
- if (c == param->hot) {
- /* suspend input */
- input_status = 0;
- if (status->pid != -1)
- kill(status->pid, SIGINT);
-
- /*
- * Put in terminal in the curses mode and add
- * the status line at the bottom.
- */
- fixterm();
- status_line(NULL);
- #ifndef OLDCURSES
- keypad(stdscr, 1);
- #endif /* OLDCURSES */
- i = wgetch(stdscr);
- /* map the hot key to -1 */
- if (i == param->hot)
- i = -1;
- /*
- * Load the virtual screen from the file. On
- * very busy systems, the file might not "appear"
- * fast enough for this routine to detect it.
- * Or worse, it may contain partially written
- * information.
- */
- load_vs();
- /* look for options */
- k = -1;
- switch (i) {
- case -1: /* 2 'hots' means send 1 */
- k = param->hot;
- break;
- case '0': /* help screen */
- help_screen(param->ascii_hot, status->fd);
- break;
- case 'd':
- case 'D': /* dialing directory */
- if (dial_menu())
- input_status = dial_win();
- break;
- case 'r':
- case 'R': /* redial */
- if (redial(status->fd))
- input_status = dial_win();
- break;
- case 'p':
- case 'P': /* line settings */
- if (line_set_menu(status->fd)) {
- line_set();
- }
- break;
- case 'x':
- case 'X': /* exit */
- pexit(status->fd);
- break;
- case '4': /* Unix gateway */
- native_shell();
- break;
- case 'i':
- case 'I': /* Program info screen */
- info(status->fd);
- break;
- case 's': /* setup menu */
- case 'S':
- setup_menu(status->fd);
- break;
- case 'c': /* clear the screen */
- case 'C':
- unlink(status->vs_path);
- clear();
- clear_absolute(stdscr);
- break;
- case 'b':
- case 'B': /* Change directory */
- if ((new_dir = change_dir(status->fd)) != NULL) {
- chdir(new_dir);
- free_ptr(new_dir);
- }
- break;
- case 'e':
- case 'E': /* toggle duplex */
- if (dir->duplex[dir->d_cur] == 'F')
- dir->duplex[dir->d_cur] = 'H';
- else
- dir->duplex[dir->d_cur] = 'F';
- line_set();
-
- /* show changes */
- status_line(NULL);
- k = wait_key(stdscr, 2);
- break;
- case 'h':
- case 'H': /* hang up phone */
- hang_up(1);
- input_off();
- break;
- case 'l':
- case 'L': /* toggle printer */
- status->print = status->print ? 0 : 1;
- if (status->pid != -1)
- kill(status->pid, SIGUSR2);
-
- /* show changes */
- status_line(NULL);
- k = wait_key(stdscr, 2);
- break;
- case '3': /* toggle CR CR/LF */
- if (!strcmp(param->cr_in, "CR"))
- param->cr_in = strdup("CR/LF");
- else
- param->cr_in = strdup("CR");
- input_off();
- input_status = 1;
-
- /* show changes */
- status_line(NULL);
- k = wait_key(stdscr, 2);
- break;
- case '7': /* break key */
- if (status->fd != -1)
- ioctl(status->fd, TCSBRK, 0);
-
- status_line(" break");
- break;
- #ifndef OLDCURSES
- case KEY_UP:
- #endif /* OLDCURSES */
- case 'u':
- case 'U': /* send files */
- input_status = xfer_menu(1);
- break;
- #ifndef OLDCURSES
- case KEY_DOWN:
- case '\n':
- #endif /* OLDCURSES */
- case 'n':
- case 'N': /* receive files */
- input_status = xfer_menu(0);
- break;
- case 'f':
- case 'F': /* list directory */
- list_dir(status->fd);
- break;
- case 'g': /* screen dump */
- case 'G':
- screen_dump();
- status_line(" screen dump");
- k = wait_key(stdscr, 2);
- break;
- case '1': /* data logging */
- input_status = data_logging(status->fd);
- break;
- case '2': /* toggle log */
- if (!strcmp(status->log_path, "NOT_DEFINED")) {
- beep();
- status_line(" no log file");
- k = wait_key(stdscr, 2);
- break;
- }
- status->log = status->log ? 0 : 1;
- if (status->pid != -1)
- kill(status->pid, SIGUSR1);
-
- /* show changes */
- status_line(NULL);
- k = wait_key(stdscr, 2);
- break;
- default:
- fputc(7, stderr);
- break;
- }
-
- /*
- * Repaint the stdscr (if we are already talking),
- * get the terminal out of the curses mode and
- * into the raw mode.
- */
- if (status->fd != -1) {
- touchwin(stdscr);
- refresh();
- }
- resetterm();
- cr_lf = raw_mode();
- /* re-start input routine */
- if (input_status)
- input_on();
- else {
- /* un-suspend (is that a word?) */
- if (status->pid != -1)
- kill(status->pid, SIGINT);
- }
- /*
- * If you pressed a key during one of the sleeping
- * periods (typically the delay to see the status
- * line change), let the keyboard value fall thru
- * to the write() below.
- */
- if (k == -1)
- continue;
- c = k;
- }
- write(status->fd, &c, 1);
- /* map cr to cr_lf ? */
- if (cr_lf)
- write(status->fd, &lf, 1);
- }
- }
-
- /*
- * Put the terminal in the raw mode. We've divided up the responsibility
- * for the line settings options between the serial port and the tty driver
- * for the stdin and stdout. The return code is the cr_lf mapping.
- */
-
- int
- raw_mode()
- {
- int ret_code;
- struct termio tbuf;
-
- ioctl(0, TCGETA, &tbuf);
-
- tbuf.c_cc[4] = 1; /* VMIN */
- tbuf.c_cc[5] = 0; /* VTIME */
- tbuf.c_iflag = 0;
- tbuf.c_oflag = 0;
- tbuf.c_lflag = 0;
-
- /*
- * Some of the output processing options have to be faked...
- * Unfortunately, adding a LF to CR is one of them.
- */
- ret_code = 0;
- if (!strcmp(param->cr_out, "CR/LF"))
- ret_code++;
- /* duplex */
- if (dir->duplex[dir->d_cur] == 'H')
- tbuf.c_lflag = ECHO;
-
- ioctl(0, TCSETA, &tbuf);
- ioctl(0, TCFLSH, 2);
- return(ret_code);
- }
-
- /*
- * Fire up the input routine...
- */
-
- void
- input_on()
- {
- int pid, add_lf;
- /* if no tty, or already on */
- if (status->pid != -1 || status->fd == -1)
- return;
- /* input cr translations */
- add_lf = !strcmp(param->cr_in, "CR/LF");
-
- /* fork the input routine */
- if (!(pid = fork()))
- input(status->fd, add_lf, status->log, status->print,
- LINES, COLS, status->vs_path, status->log_path);
-
- status->pid = pid;
- return;
- }
-
- /*
- * shut it down...
- */
-
- void
- input_off()
- {
- if (status->pid != -1) {
- kill(status->pid, SIGTERM);
- status->pid = -1;
- }
- return;
- }
-
- /*
- * Hang up the phone but remain in the pcomm command state.
- */
-
- void
- hang_up(verbose)
- int verbose;
- {
- void send_str(), status_line();
- #ifdef UNIXPC
- char buf[20], *strcpy(), *strcat();
- #endif /* UNIXPC */
-
- /* anything to hang up? */
- if (modem->m_cur == -1)
- return;
-
- if (verbose)
- status_line("disconnecting");
- /* special case for OBM */
- #ifdef UNIXPC
- if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
- ioctl(status->fd, PIOCDISC);
- /*
- * The PIOCDISC ioctl prevents writes on the file descriptor!
- * No other phone(7) ioctl can fix it... Whatever it does, it
- * seems to escape detection with PIOCGETA and TCGETA. The
- * best I can do is close the descriptor and start over.
- */
- close(status->fd);
- strcpy(buf, "/dev/");
- strcat(buf, modem->tty[modem->t_cur]);
- status->fd = open(buf, O_RDWR|O_NDELAY);
- fcntl(status->fd, F_SETFL, fcntl(status->fd, F_GETFL, 0) & ~O_NDELAY);
- }
- else
- #endif /* UNIXPC */
- send_str(modem->hangup[modem->m_cur]);
-
- if (verbose)
- status_line(NULL);
- return;
- }
-