home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / pcomm-2.0.2 / part03 / terminal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  8.6 KB  |  422 lines

  1. /*
  2.  * Start the terminal dialogue, scan the TTY, keyboard, and the "script"
  3.  * for input, watch for the hot key so we can execute an option.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <curses.h>
  8. #include <signal.h>
  9. #include "config.h"
  10. #include "dial_dir.h"
  11. #include "ipc.h"
  12. #include "misc.h"
  13. #include "modem.h"
  14. #include "param.h"
  15. #include "status.h"
  16. #include "xmodem.h"
  17.  
  18. #ifdef BSD
  19. #ifndef SIGCLD
  20. #define SIGCLD SIGCHLD
  21. #endif /* SIGCLD */
  22. #include <sys/file.h>
  23. #else /* BSD */
  24. #include <fcntl.h>
  25. #endif /* BSD */
  26.  
  27. #ifdef UNIXPC
  28. #include <sys/phone.h>
  29. #endif /* UNIXPC */
  30.  
  31. static void key_input();
  32. static int cr_lf;
  33.  
  34. void
  35. terminal(script)
  36. char *script;
  37. {
  38.     extern int fd;
  39.     int ret_code;
  40.     void tty_input(), st_line(), term_mode(), cmd_input(), do_script();
  41.     void is_active(), ipc_init();
  42.  
  43.     ipc_init(fd, status->cmd_ipc);
  44.                     /* if not starting with -f option */
  45.     if (dir->q_num[0] == -1) {
  46.         erase();
  47.         refresh();
  48.         st_line("");
  49.     }
  50.                     /* put stdin/stdout in terminal mode */
  51.     resetterm();
  52.     term_mode();
  53.     cr_lf = !strcmp(param->cr_out, "CR/LF");
  54.  
  55.                     /* play a script from command line */
  56.     if (script != NULL && *script != '\0')
  57.         do_script(script);
  58.  
  59.                     /* the main loop ! */
  60.     /* CONSTCOND */
  61.     while (1) {
  62.         ret_code = ipc_poll(fd, status->cmd_ipc);
  63.  
  64.         if (ret_code & TTY_READY)
  65.             tty_input();
  66.  
  67.         if (ret_code & KEY_READY)
  68.             key_input();
  69.  
  70.         /* 
  71.          * This is the reason for the 1 sec "timeout" of the
  72.          * poll/select call... to periodically check the status
  73.          * of the "script" for input.
  74.          */
  75.         if (status->dup_fd != -1)
  76.             is_active();
  77.                     /* do a command from a script */
  78.         if (ret_code & CMD_READY)
  79.             cmd_input();
  80.     }
  81.     /* NOTREACHED */
  82. }
  83.  
  84. /*
  85.  * There is something ready to be read from the keyboard.
  86.  */
  87.  
  88. static void
  89. key_input()
  90. {
  91.     extern int fd;
  92.     int i, k;
  93.     char c, lf=10, *str_rep(), *keymac, *script, *script_menu();
  94.     void help_screen(), line_set(), n_shell(), load_vs(), send_str();
  95.     void release_port(), list_dir(), pexit(), st_line(), chg_dir();
  96.     void screen_dump(), info(), term_mode(), macro(), stop_script();
  97.     void setup_menu(), xfer_menu(), data_logging(), pass_thru();
  98.     void half_duplex(), do_script(), vs_clear(), tty_restart();
  99.     void log_toggle(), lpr_toggle();
  100.  
  101.     read(0, &c, 1);
  102.     c &= 0x7f;
  103.                     /* stop the script? */
  104.     if (status->dup_fd != -1 && c == ESC) {
  105.         stop_script();
  106.         return;
  107.     }
  108.                     /* is it the hot key? */
  109.     if (c == param->hot_key) {
  110.  
  111.         script = NULL;
  112.         /*
  113.          * Put the terminal in the curses mode, load the
  114.          * virtual screen and add the status line at the bottom.
  115.          */
  116.         fixterm();
  117.         load_vs();
  118.         st_line("");
  119. #ifndef OLDCURSES
  120.         keypad(stdscr, TRUE);
  121. #endif /* OLDCURSES */
  122.         i = wgetch(stdscr);
  123.                     /* map an additional hot key to -1 */
  124.         if (i == param->hot_key)
  125.             i = -1;
  126.  
  127.         keymac = "";
  128.                     /* look for options */
  129.         k = -1;
  130.         switch (i) {
  131.             case -1:    /* 2 "hots" means send 1 */
  132.                 k = param->hot_key;
  133.                 break;
  134.             case '0':    /* help screen */
  135.                 help_screen(param->ascii_hot);
  136.                 break;
  137.             case 'd':
  138.             case 'D':    /* dialing directory */
  139.                 if (dial_menu()) {
  140.                     if (!dial_win(25))
  141.                         script = dir->aux[0];
  142.                 }
  143.                 break;
  144.             case 'r':
  145.             case 'R':    /* redial */
  146.                 if (redial()) {
  147.                     if (!dial_win(25))
  148.                         script = dir->aux[0];
  149.                 }
  150.                 break;
  151.             case 'm':
  152.             case 'M':    /* keyboard macros */
  153.                 macro();
  154.                 break;
  155.             case 'p':
  156.             case 'P':    /* line settings */
  157.                 if (ls_menu())
  158.                     line_set();
  159.                 break;
  160.             case 'x':
  161.             case 'X':    /* exit */
  162.                 pexit();
  163.                 break;
  164.             case '4':    /* Unix gateway */
  165.                 n_shell();
  166.                 break;
  167.             case '5':    /* Command files */
  168.                 script = script_menu();
  169.                 break;
  170.             case 'i':
  171.             case 'I':    /* program info screen */
  172.                 info(MANUAL_CLEAR);
  173.                 break;
  174.             case 's':    /* setup menu */
  175.             case 'S':
  176.                 setup_menu();
  177.                 break;
  178.             case 'c':    /* clear the screen */
  179.             case 'C':
  180.                 erase();
  181.                 vs_clear(0);
  182.                 break;
  183.             case 'b':
  184.             case 'B':    /* change directory */
  185.                 chg_dir();
  186.                 break;
  187.             case 'e':
  188.             case 'E':    /* toggle duplex */
  189.                 if (dir->duplex[0] == 'F')
  190.                     dir->duplex[0] = 'H';
  191.                 else
  192.                     dir->duplex[0] = 'F';
  193.  
  194.                     /* show changes */
  195.                 st_line("");
  196.                 k = wait_key(stdscr, 2);
  197.                 break;
  198.             case 'h':
  199.             case 'H':    /* hang up phone */
  200.                 release_port(VERBOSE);
  201.                 break;
  202.             case 'l':
  203.             case 'L':    /* print toggle */
  204.                 lpr_toggle();
  205.                     /* show changes */
  206.                 st_line("");
  207.                 k = wait_key(stdscr, 2);
  208.                 break;
  209.             case '3':    /* toggle CR - CR/LF */
  210.                 if (!strcmp(param->cr_in, "CR"))
  211.                     param->cr_in = str_rep(param->cr_in, "CR/LF");
  212.                 else 
  213.                     param->cr_in = str_rep(param->cr_in, "CR");
  214.                     /* show changes */
  215.                 st_line("");
  216.                 k = wait_key(stdscr, 2);
  217.                 break;
  218.             case '7':    /* break key */
  219.                 if (fd != -1)
  220.                     tty_break(fd);
  221.  
  222.                 st_line("   break");
  223.                 break;
  224. #ifndef    OLDCURSES
  225.             case KEY_UP:
  226. #endif /* OLDCURSES */
  227.             case 'u':
  228.             case 'U':    /* send files */
  229.                 xfer_menu(UP_LOAD);
  230.                 break;
  231. #ifndef OLDCURSES
  232.             case KEY_DOWN:
  233.             case '\n':
  234. #endif /* OLDCURSES */
  235.             case 'n':
  236.             case 'N':    /* receive files */
  237.                 xfer_menu(DOWN_LOAD);
  238.                 break;
  239.             case 't':
  240.             case 'T':
  241.                 pass_thru();
  242.                 break;
  243.             case 'f':
  244.             case 'F':    /* list directory */
  245.                 list_dir();
  246.                 break;
  247.             case 'g':    /* screen dump */
  248.             case 'G':
  249.                 screen_dump();
  250.                 st_line(" screen dump");
  251.                 k = wait_key(stdscr, 2);
  252.                 break;
  253.             case '1':    /* data logging */
  254.                 data_logging();
  255.                 break;
  256.             case '2':    /* toggle log */
  257.                 if (!strcmp(status->log_path, "NOT_DEFINED")) {
  258.                     beep();
  259.                     st_line(" no log file");
  260.                     k = wait_key(stdscr, 2);
  261.                     break;
  262.                 }
  263.                 log_toggle();
  264.                     /* show changes */
  265.                 st_line("");
  266.                 k = wait_key(stdscr, 2);
  267.                 break;
  268.             /*
  269.              * The following are the keyboard macros
  270.              * corresponding to the shifted number keys.
  271.              * (Too many keys... [control] [A] [shift] [1]
  272.              * is hardly a shortcut!)
  273.              */
  274.             case '!':
  275.                 keymac = param->mac_1;
  276.                 break;
  277.             case '@':
  278.                 keymac = param->mac_2;
  279.                 break;
  280.             case '#':
  281.                 keymac = param->mac_3;
  282.                 break;
  283.             case '$':
  284.                 keymac = param->mac_4;
  285.                 break;
  286.             case '%':
  287.                 keymac = param->mac_5;
  288.                 break;
  289.             case '^':
  290.                 keymac = param->mac_6;
  291.                 break;
  292.             case '&':
  293.                 keymac = param->mac_7;
  294.                 break;
  295.             case '*':
  296.                 keymac = param->mac_8;
  297.                 break;
  298.             case '(':
  299.                 keymac = param->mac_9;
  300.                 break;
  301.             case ')':
  302.                 keymac = param->mac_0;
  303.                 break;
  304.             default:
  305.                 fputc(BEL, stderr);
  306.                 break;
  307.         }
  308.  
  309.         /*
  310.          * Repaint the stdscr (if we are already talking),
  311.          * get the stdin/stdout out of the curses mode and
  312.          * into the terminal mode.
  313.          */
  314.         if (fd != -1) {
  315.             touchwin(stdscr);
  316.             refresh();
  317.         }
  318.         resetterm();
  319.         term_mode();
  320.                     /* restart stopped flow control */
  321.         tty_restart();
  322.  
  323.         /*
  324.          * Some of the output processing options have to be
  325.          * faked...  Unfortunately, adding a LF to CR on
  326.          * output is one of them.
  327.          */
  328.         cr_lf = !strcmp(param->cr_out, "CR/LF");
  329.  
  330.                     /* play the script */
  331.         if (script != NULL && *script != '\0')
  332.             do_script(script);
  333.  
  334.                     /* send the macro */
  335.         if (*keymac != '\0')
  336.             send_str(keymac, FAST);
  337.  
  338.         /*
  339.          * If you pressed a key during one of the sleeping
  340.          * periods (typically the delay to see the status
  341.          * line change), let the keyboard value fall thru
  342.          * to the write() below.
  343.          */
  344.         if (k == -1)
  345.             return;
  346.         c = (char) k;
  347.     }        
  348.                     /* ignore errors if fd == -1 */
  349.     write(fd, &c, 1);
  350.  
  351.     /*
  352.      * If you're using the half duplex mode, characters don't get
  353.      * echoed by the driver (cause you don't type them!)
  354.      */
  355.     if (dir->duplex[0] == 'H')
  356.         half_duplex(c);
  357.                     /* map cr to cr_lf? */
  358.     if (c == '\r' && cr_lf) {
  359.         write(fd, &lf, 1);
  360.  
  361.         if (dir->duplex[0] == 'H') {
  362.             write(1, &lf, 1);
  363.             half_duplex(lf);
  364.         }
  365.     }
  366.     return;
  367. }
  368.  
  369. /*
  370.  * Hang up the phone but remain in the Pcomm command state.  Uses the
  371.  * hang_up string only, does *not* drop the DTR!
  372.  */
  373.  
  374. void
  375. hang_up(verbose)
  376. int verbose;
  377. {
  378.     extern int fd;
  379.     void send_str(), st_line(), tty_restart();
  380.     unsigned int sleep();
  381.                     /* sanity checking */
  382.     if (modem == NULL)
  383.         return;
  384.                     /* anything to hang up? */
  385.     if (modem->m_cur == -1 || fd == -1)
  386.         return;
  387.  
  388.     if (verbose)
  389.         st_line("disconnecting");
  390.                     /* special case for OBM */
  391.     if (!strcmp(modem->mname[modem->m_cur], "OBM")) /* EMPTY */ {
  392. #ifdef UNIXPC
  393.         char buf[80];
  394.         void line_set();
  395.  
  396.         ioctl(fd, PIOCDISC);
  397.         /*
  398.          * The PIOCDISC ioctl screws up the file descriptor!!!
  399.          * No other phone(7) ioctl can fix it.  Whatever it does,
  400.          * it seems to escape detection with PIOCGETA and TCGETA.
  401.          * The best I can do is close the port and start over.
  402.          */
  403.         sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
  404.         close(fd);
  405.         fd = open(buf, O_RDWR|O_NDELAY);
  406.         line_set();
  407.         tty_noblock(fd, FALSE);
  408. #endif /* UNIXPC */
  409.     }
  410.     else {
  411.         tty_restart();
  412.         send_str(modem->hang_up[modem->m_cur], SLOW);
  413.         sleep(1);
  414.     }
  415.  
  416.     if (verbose)
  417.         st_line("");
  418.  
  419.     status->connected = 0;
  420.     return;
  421. }
  422.