home *** CD-ROM | disk | FTP | other *** search
- /*
- * Start the terminal dialogue, scan the TTY, keyboard, and the "script"
- * for input, watch for the hot key so we can execute an option.
- */
-
- #include <stdio.h>
- #include <curses.h>
- #include <signal.h>
- #include "config.h"
- #include "dial_dir.h"
- #include "ipc.h"
- #include "misc.h"
- #include "modem.h"
- #include "param.h"
- #include "status.h"
- #include "xmodem.h"
-
- #ifdef BSD
- #ifndef SIGCLD
- #define SIGCLD SIGCHLD
- #endif /* SIGCLD */
- #include <sys/file.h>
- #else /* BSD */
- #include <fcntl.h>
- #endif /* BSD */
-
- #ifdef UNIXPC
- #include <sys/phone.h>
- #endif /* UNIXPC */
-
- static void key_input();
- static int cr_lf;
-
- void
- terminal(script)
- char *script;
- {
- extern int fd;
- int ret_code;
- void tty_input(), st_line(), term_mode(), cmd_input(), do_script();
- void is_active(), ipc_init();
-
- ipc_init(fd, status->cmd_ipc);
- /* if not starting with -f option */
- if (dir->q_num[0] == -1) {
- erase();
- refresh();
- st_line("");
- }
- /* put stdin/stdout in terminal mode */
- resetterm();
- term_mode();
- cr_lf = !strcmp(param->cr_out, "CR/LF");
-
- /* play a script from command line */
- if (script != NULL && *script != '\0')
- do_script(script);
-
- /* the main loop ! */
- /* CONSTCOND */
- while (1) {
- ret_code = ipc_poll(fd, status->cmd_ipc);
-
- if (ret_code & TTY_READY)
- tty_input();
-
- if (ret_code & KEY_READY)
- key_input();
-
- /*
- * This is the reason for the 1 sec "timeout" of the
- * poll/select call... to periodically check the status
- * of the "script" for input.
- */
- if (status->dup_fd != -1)
- is_active();
- /* do a command from a script */
- if (ret_code & CMD_READY)
- cmd_input();
- }
- /* NOTREACHED */
- }
-
- /*
- * There is something ready to be read from the keyboard.
- */
-
- static void
- key_input()
- {
- extern int fd;
- int i, k;
- char c, lf=10, *str_rep(), *keymac, *script, *script_menu();
- void help_screen(), line_set(), n_shell(), load_vs(), send_str();
- void release_port(), list_dir(), pexit(), st_line(), chg_dir();
- void screen_dump(), info(), term_mode(), macro(), stop_script();
- void setup_menu(), xfer_menu(), data_logging(), pass_thru();
- void half_duplex(), do_script(), vs_clear(), tty_restart();
- void log_toggle(), lpr_toggle();
-
- read(0, &c, 1);
- c &= 0x7f;
- /* stop the script? */
- if (status->dup_fd != -1 && c == ESC) {
- stop_script();
- return;
- }
- /* is it the hot key? */
- if (c == param->hot_key) {
-
- script = NULL;
- /*
- * Put the terminal in the curses mode, load the
- * virtual screen and add the status line at the bottom.
- */
- fixterm();
- load_vs();
- st_line("");
- #ifndef OLDCURSES
- keypad(stdscr, TRUE);
- #endif /* OLDCURSES */
- i = wgetch(stdscr);
- /* map an additional hot key to -1 */
- if (i == param->hot_key)
- i = -1;
-
- keymac = "";
- /* look for options */
- k = -1;
- switch (i) {
- case -1: /* 2 "hots" means send 1 */
- k = param->hot_key;
- break;
- case '0': /* help screen */
- help_screen(param->ascii_hot);
- break;
- case 'd':
- case 'D': /* dialing directory */
- if (dial_menu()) {
- if (!dial_win(25))
- script = dir->aux[0];
- }
- break;
- case 'r':
- case 'R': /* redial */
- if (redial()) {
- if (!dial_win(25))
- script = dir->aux[0];
- }
- break;
- case 'm':
- case 'M': /* keyboard macros */
- macro();
- break;
- case 'p':
- case 'P': /* line settings */
- if (ls_menu())
- line_set();
- break;
- case 'x':
- case 'X': /* exit */
- pexit();
- break;
- case '4': /* Unix gateway */
- n_shell();
- break;
- case '5': /* Command files */
- script = script_menu();
- break;
- case 'i':
- case 'I': /* program info screen */
- info(MANUAL_CLEAR);
- break;
- case 's': /* setup menu */
- case 'S':
- setup_menu();
- break;
- case 'c': /* clear the screen */
- case 'C':
- erase();
- vs_clear(0);
- break;
- case 'b':
- case 'B': /* change directory */
- chg_dir();
- break;
- case 'e':
- case 'E': /* toggle duplex */
- if (dir->duplex[0] == 'F')
- dir->duplex[0] = 'H';
- else
- dir->duplex[0] = 'F';
-
- /* show changes */
- st_line("");
- k = wait_key(stdscr, 2);
- break;
- case 'h':
- case 'H': /* hang up phone */
- release_port(VERBOSE);
- break;
- case 'l':
- case 'L': /* print toggle */
- lpr_toggle();
- /* show changes */
- st_line("");
- k = wait_key(stdscr, 2);
- break;
- case '3': /* toggle CR - CR/LF */
- if (!strcmp(param->cr_in, "CR"))
- param->cr_in = str_rep(param->cr_in, "CR/LF");
- else
- param->cr_in = str_rep(param->cr_in, "CR");
- /* show changes */
- st_line("");
- k = wait_key(stdscr, 2);
- break;
- case '7': /* break key */
- if (fd != -1)
- tty_break(fd);
-
- st_line(" break");
- break;
- #ifndef OLDCURSES
- case KEY_UP:
- #endif /* OLDCURSES */
- case 'u':
- case 'U': /* send files */
- xfer_menu(UP_LOAD);
- break;
- #ifndef OLDCURSES
- case KEY_DOWN:
- case '\n':
- #endif /* OLDCURSES */
- case 'n':
- case 'N': /* receive files */
- xfer_menu(DOWN_LOAD);
- break;
- case 't':
- case 'T':
- pass_thru();
- break;
- case 'f':
- case 'F': /* list directory */
- list_dir();
- break;
- case 'g': /* screen dump */
- case 'G':
- screen_dump();
- st_line(" screen dump");
- k = wait_key(stdscr, 2);
- break;
- case '1': /* data logging */
- data_logging();
- break;
- case '2': /* toggle log */
- if (!strcmp(status->log_path, "NOT_DEFINED")) {
- beep();
- st_line(" no log file");
- k = wait_key(stdscr, 2);
- break;
- }
- log_toggle();
- /* show changes */
- st_line("");
- k = wait_key(stdscr, 2);
- break;
- /*
- * The following are the keyboard macros
- * corresponding to the shifted number keys.
- * (Too many keys... [control] [A] [shift] [1]
- * is hardly a shortcut!)
- */
- case '!':
- keymac = param->mac_1;
- break;
- case '@':
- keymac = param->mac_2;
- break;
- case '#':
- keymac = param->mac_3;
- break;
- case '$':
- keymac = param->mac_4;
- break;
- case '%':
- keymac = param->mac_5;
- break;
- case '^':
- keymac = param->mac_6;
- break;
- case '&':
- keymac = param->mac_7;
- break;
- case '*':
- keymac = param->mac_8;
- break;
- case '(':
- keymac = param->mac_9;
- break;
- case ')':
- keymac = param->mac_0;
- break;
- default:
- fputc(BEL, stderr);
- break;
- }
-
- /*
- * Repaint the stdscr (if we are already talking),
- * get the stdin/stdout out of the curses mode and
- * into the terminal mode.
- */
- if (fd != -1) {
- touchwin(stdscr);
- refresh();
- }
- resetterm();
- term_mode();
- /* restart stopped flow control */
- tty_restart();
-
- /*
- * Some of the output processing options have to be
- * faked... Unfortunately, adding a LF to CR on
- * output is one of them.
- */
- cr_lf = !strcmp(param->cr_out, "CR/LF");
-
- /* play the script */
- if (script != NULL && *script != '\0')
- do_script(script);
-
- /* send the macro */
- if (*keymac != '\0')
- send_str(keymac, FAST);
-
- /*
- * 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)
- return;
- c = (char) k;
- }
- /* ignore errors if fd == -1 */
- write(fd, &c, 1);
-
- /*
- * If you're using the half duplex mode, characters don't get
- * echoed by the driver (cause you don't type them!)
- */
- if (dir->duplex[0] == 'H')
- half_duplex(c);
- /* map cr to cr_lf? */
- if (c == '\r' && cr_lf) {
- write(fd, &lf, 1);
-
- if (dir->duplex[0] == 'H') {
- write(1, &lf, 1);
- half_duplex(lf);
- }
- }
- return;
- }
-
- /*
- * Hang up the phone but remain in the Pcomm command state. Uses the
- * hang_up string only, does *not* drop the DTR!
- */
-
- void
- hang_up(verbose)
- int verbose;
- {
- extern int fd;
- void send_str(), st_line(), tty_restart();
- unsigned int sleep();
- /* sanity checking */
- if (modem == NULL)
- return;
- /* anything to hang up? */
- if (modem->m_cur == -1 || fd == -1)
- return;
-
- if (verbose)
- st_line("disconnecting");
- /* special case for OBM */
- if (!strcmp(modem->mname[modem->m_cur], "OBM")) /* EMPTY */ {
- #ifdef UNIXPC
- char buf[80];
- void line_set();
-
- ioctl(fd, PIOCDISC);
- /*
- * The PIOCDISC ioctl screws up 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 port and start over.
- */
- sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
- close(fd);
- fd = open(buf, O_RDWR|O_NDELAY);
- line_set();
- tty_noblock(fd, FALSE);
- #endif /* UNIXPC */
- }
- else {
- tty_restart();
- send_str(modem->hang_up[modem->m_cur], SLOW);
- sleep(1);
- }
-
- if (verbose)
- st_line("");
-
- status->connected = 0;
- return;
- }
-