home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / HTERM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-12  |  19.8 KB  |  854 lines

  1. /*
  2. ** hterm.c: halca terminal emulator main
  3.  *
  4.  * Author: HIRANO Satoshi
  5.  *
  6.  * (C) 1986 Halca Computer Science Laboratory UEC  TM
  7.  *          University of Electro Communications
  8.  *          University of Tokyo
  9.  *
  10.  * 
  11.  * Edition history:
  12.  * 1.0 86/10/20 Halca.Hirano creation for PC-9801
  13.  * 1.2 87/01/09 Halca.Hirano support kana character
  14.  * 1.3 87/01/13 Halca.Hirano able to change print spacing
  15.  * 1.4 87/02/23 Halca.Hirano IBM-PC (MS-DOS & MSC) support
  16.  * 1.5 87/06/09 Halca.Hirano fix PC-9801 keyboard bug
  17.  * 2.1 87/06/17 Halca.Hirano combine hterm/pc hterm/98 into one source
  18.  * 2.2 89/05/16 Halca.Hirano 
  19.  *    ---- V2.2 distribution ----
  20.  * 2.3 89/06/15 Halca.Hirano
  21.  *    1  remove #else
  22.  * 2.4 89/06/21 Halca.Hirano add CRT saver hook
  23.  * 2.5 89/07/20 Halca.Hirano add redial, upload, download, CTRL-PFkey
  24.  * 2.6 89/07/26 Halca.Hirano change set-up file search method
  25.  * 2.6 89/07/28 Halca.Hirano support multiple ports, add line option
  26.  *    ---- V2.3.-1 distribution ----
  27.  * 2.7 89/09/25 Halca.Hirano add paste key
  28.  *      ---- V2.4.0 distribution ----
  29.  * 2.8 89/10/08 Halca.Hirano add auto login
  30.  * 2.9 89/11/10 Tominaga@Titech ported to J3100, now we can use 38400 baud on IBM-PC
  31.  * 3.1 89/11/23 Halca.Hirano fix warning message bug
  32.  * 3.2 89/11/23 Halca.Hirano add critical error message handler
  33.  * 3.3 89/12/03 Halca.Hirano add bs key watcher
  34.  *    add hterm control by meta-function keys
  35.  * 3.4 90/06/17 Halca.Hirano support soft font
  36.  */
  37.  
  38. static char version[] = "$Header: hterm.cv  1.19  90/07/05 03:27:10  hirano  Exp $";
  39.  
  40. #include <stdio.h>
  41. #include <ctype.h>
  42. #include <time.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #define MAIN 1
  46. #include "config.h"
  47. #include "hterm.h"
  48. #include "option.h"
  49. #include "default.h"
  50. #include "global.h"
  51. #include "version.h"
  52. #ifdef FEP
  53. #include "fepctrl.h"
  54. #endif /* FEP */
  55.  
  56. /*
  57. ** messages
  58.  */
  59. char *helpmsg = "\
  60. Function: terminal system\n\
  61. Syntax: hterm [options] [set-up file]\n\
  62. Example: hterm -b38400 -l2   (com2: 38400 baud)\n\
  63.          hterm -d seiken     (call seiken)\n\
  64. Options:\n\
  65.   -ns     don't read set-up file\n\
  66.   -d      auto dialing\n\
  67.   -nd     no auto dialing\n\
  68.   -l<dev> serial port device\n\
  69.   -f[fontfile] soft font mode\n\
  70. ";
  71.  
  72. #ifdef IBMPC
  73. char *machineOption = "\
  74.   -b<num> set baudrate to 300,1200,2400,4800,9600,19200,38400\n\
  75. ";
  76. #endif /* IBMPC */
  77.  
  78. #ifdef J3100
  79. char *machineOption = "\
  80.   -b<num> set baudrate to 300,1200,2400,4800,9600,19200,38400\n\
  81. ";
  82. #endif /* J3100 */
  83.  
  84. #ifdef PC98
  85. char *machineOption = "\
  86.   -b<num> set baudrate to 300,1200,2400,4800,9600,19200,38400\n\
  87.   -a      ANSI keyboard mode\n\
  88.   -p      PC9801 keyboard mode\n\
  89. ";
  90. #endif /* PC98 */
  91.  
  92. static int optSoftFont;
  93. static char *optFontName;
  94. static int mainArgc;
  95. static char **mainArgv;
  96.  
  97. void initialize(void );
  98. void options(int argc,char * *argv);
  99. void cant(void );
  100. void doDial(short c);
  101. void htermCtrl(unsigned short c);
  102. void bsKeyWatcher(void );
  103.  
  104. /*
  105. ** main()
  106.  *
  107.  * hterm main loop
  108.  */
  109. main(argc, argv)
  110. char **argv;
  111. {
  112.     register short c;
  113.     int pri;
  114.  
  115.     time(&starTime);
  116.     mainArgc = argc;
  117.     mainArgv = argv;
  118.     initialize();
  119.  
  120.     timerValue = timerLoadValue;
  121.     /*
  122.      * dialing at startup
  123.      */
  124.     redial = dialStartup;
  125.  
  126.     /*
  127.      * hterm main loop
  128.      */
  129.     for (;;) {
  130.         /*
  131.          * display data from the remote system to console
  132.          */
  133.         for (pri = 0; pri < SERIAL_PRIORITY; pri++) {
  134.             if (online && (c = getSerial()) != -1) {
  135.                 decodeAnsi(c & cMask);
  136.                 timerValue = timerLoadValue;
  137.             }
  138.             if (redial)
  139.                 doDial(c);
  140.         }
  141.         /*
  142.          * send user's key to the remote system
  143.          */
  144.         if ((c = keyin()) != -1) {
  145.             redial = NO;            /* disturb dialing                */
  146.             /* timerValue is updated in keyin() */
  147.             if (c && ((c & 0x00ff) == 0))
  148.                 htermCtrl(c);        /* special key controls hterm    */
  149.             else
  150.                 if (!maskFlag)         /* if not XOFFed from host        */
  151.                     outPort(c);        /* send it                        */
  152.         }
  153.         if (!maskFlag) {
  154.             /*
  155.              * file upload
  156.              */
  157.             if (upLoading) {
  158.                 if ((c = upGet()) == EOF) {
  159.                     upStop();
  160.                     conPrint("\n\r");
  161.                     putComment("up load done", msg_null);
  162.                 } else if (c != -2)
  163.                     outPort(c);
  164.             }
  165. #ifdef COPY_PASTE
  166.             /*
  167.              * history paste
  168.              */
  169.             if (copyBufferSize)
  170.                 if ((c = getCopyBuffer()) != ERR)
  171.                     outPort(c);
  172. #endif /* COPY_PASTE */
  173.         }
  174.  
  175. #ifdef BS_WATCHER
  176.         /*
  177.          * BS key watcher; indicate 'take a rest' by too many BS/DEL 
  178.          */
  179.         if (bsKeyWatcherTimer <= 0 && bsKeyRatio)
  180.             bsKeyWatcher();
  181. #endif /* BS_WATCHER */
  182.  
  183.         /*
  184.          * CRT saver
  185.          */
  186.         if (timerValue <= 0 && saver) {
  187.             CRTSaver();
  188.         }
  189.     }
  190. }
  191.  
  192. void initialize()
  193. {
  194.     char *path, *diag, *diag2 = 0;
  195.     int flag;
  196.  
  197.     optBaudrate = optAsckey = optRedial = optPortNo = -1;
  198.     optNoSetup = optSoftFont = NO;
  199.     optFontName = (char *)NULL;
  200.     setupSpecified = NO;
  201.     strcpy(defaultCommandLine, DEFAULT_COMMAND_LINE);
  202.  
  203.     options(mainArgc, mainArgv);    /* get option flags        */
  204.  
  205.     /*
  206.      * now we are in communication mode
  207.      */
  208.     mode = M_COMM;
  209.     /*
  210.      * DON'T USE BEEP(), BELL()
  211.      */
  212. #ifdef FEP
  213.     fep_init();            /* iniz FEP control        */
  214. #endif /* FEP */
  215. #ifdef UOP_GRAPHICS
  216.     graph_init();        /* iniz UOP graphics         */
  217. #endif /* UOP_GRAPHICS */
  218. #ifdef COPY_PASTE
  219.     editInit();            /* iniz copy&paste, history    */
  220. #endif /* COPY_PASTE */
  221. #ifdef XMODEM
  222.     xinit();            /* iniz xmodem defaults        */
  223. #endif /* XMODEM */
  224.     printInit();        /* iniz printer            */
  225.     consoleInit();        /* iniz console            */
  226.     fontInit();            /* iniz soft font        */
  227.  
  228.     /*
  229.      * Now, we can't leave without termination()! 
  230.      */
  231.     ansiInit();            /* iniz ansi decorder        */
  232.     saverInit();        /* iniz CRT Saver, timer (do before portInit()) */
  233.  
  234.     /*
  235.      * We can use beep(), bell()
  236.      */
  237.     portInit();                /* iniz serial port        */
  238.     keyInit();                /* iniz keyboard mode        */
  239.     fileInit();                /* iniz file Xfer         */
  240.     setCritHandler();        /* set critical error handler        */
  241.  
  242.     /*
  243.      * load set-up file, reset parameters as user's
  244.      */
  245.     if (setupSpecified == NO)
  246.         setFile = SETUP_FILE;
  247.     if ((path = searchPath(setFile)) == NULL)
  248.         strcpy(setFileName, setFile);    /* use    hterm.set    */
  249.     else
  250.         strcpy(setFileName, path);
  251.     if (optNoSetup)
  252.         diag = NULL;
  253.     else
  254.         diag = loadSetup(setFileName, &flag); /*  load setup file    */
  255.  
  256.     /*
  257.      * search hterm help file hterm.db
  258.      */
  259.     if ((path = searchPath(HELP_FILE)) == NULL)
  260.         strcpy(helpFileName, HELP_FILE);
  261.     else
  262.         strcpy(helpFileName, path);
  263.  
  264.  
  265.     /*
  266.      * set overridden option
  267.      */
  268.     if (optAsckey != -1)
  269.         asckey = optAsckey;
  270.     if (optBaudrate != -1L)
  271.         baudrate = (u_long)optBaudrate & 0xffff;
  272.     if (optRedial != -1)
  273.         dialStartup = optRedial;
  274.     if (optPortNo != -1)
  275.         portNo = optPortNo;
  276.     if (optSoftFont) {
  277.         softFont = YES;
  278.         if (optFontName) {
  279.             strcpy(fontName, optFontName);
  280.             if (strchr(fontName, '.') == NULL)
  281.                 strcat(fontName, ".hft");
  282.         }
  283.     }
  284.         
  285.  
  286.     /*
  287.      * reinitialize fit to user's preference
  288.      */
  289. #ifdef SOFT_FONT
  290.     if (softFont) {
  291.         attrib = eraseAttr = _NORMAL;
  292.         fprintf(stderr, "\nloading font %s ...", fontName); fflush(stderr);
  293.         diag2 = fontLoad(fontName);    /* load soft font            */
  294.         if (diag2)
  295.             softFont = NO;
  296.     }
  297. #else
  298.     softFont = NO;
  299. #endif
  300.     consoleSetup();        /* setup console            */
  301.     keySetup();            /* setup keyboard mode        */
  302.     saverSetup();        /* setup screen saver        */
  303.     fileSetup();        /* setup file utils            */
  304.     ansiSetup();
  305.  
  306.     /*
  307.      * print HELLO message
  308.      */
  309.     conPrint(versionString());
  310. #if defined IBMPC || defined J3100
  311.     conPrint("exit: ALT-F10 key    set-up: ALT-F9 key\n\n\r");
  312. #endif /* IBMPC || J3100 */
  313. #ifdef PC98
  314.     conPrint("exit: STOP key    set-up: COPY key\n\r");
  315.     conPrint(asckey ? "ANSI" : "PC9801");
  316.     conPrint(" keyboard mode\n\n\r");
  317. #endif /* PC98 */
  318.     /*
  319.      * print DIAG/WARNING messages
  320.      */
  321.     if (diag) {
  322.         conPrint(diag);
  323.         if (flag == NO) {            /* if set-up file did not be loaded    */
  324.             conPrint(".\n\rDefault setting is used.\n\r");
  325.             conPrint("Make it by 'save set-up' in set-up.\n\r");
  326.             conPrint("hterm will search 'hterm.set' on current dir, HOME and PATH at startup.\n\r");
  327.         }
  328.         conPrint("\n\r");
  329.     }
  330.     if (diag2) {    /* font load failed    */
  331.         conPrint(diag2);
  332.         conPrint(". ROM font is used.\n\r");
  333.     }
  334.  
  335.     /*
  336.      * if printMode is YES in setup, enable the printer
  337.      */
  338.     printSetup();
  339.  
  340.     /*
  341.      * reiniz serial port (this routine may put warning messages)
  342.      */
  343.     portSetup();            /* setup serial port        */    
  344.     conPrint("\n");
  345. }
  346.  
  347. void termination()
  348. {
  349.     long endTime;
  350.  
  351.     endAll();
  352.     time(&endTime);
  353.     endTime -= starTime;
  354.     printf("\x1b[1;1fhterm: User exits to the local system. (%d.%02d min)\n", (int)(endTime/60), (int)(endTime%60));
  355.     exit(0);
  356. }
  357.  
  358. /*
  359. ** resetTerminal()
  360.  *
  361.  * reset hterm
  362.  */
  363. void resetTerminal()
  364. {
  365.     int oldMode = mode;
  366.     int cursorSave = cursor;
  367.  
  368.     endAll();
  369.     initialize();
  370.     showPage1();
  371.     redial = NO;
  372.     mode = oldMode;
  373.     cursorOnOff(cursor = cursorSave);
  374. }
  375.  
  376. /*
  377. ** deinitialize all of items
  378.  */
  379. void endAll()
  380. {
  381.     if (dropER)
  382.         ER_RS_Off();        /* if drop ER, negate ER and RS    */
  383.     printEnd();
  384.     fileEnd();
  385.     portEnd();
  386.     saverEnd();
  387.     consoleEnd();
  388.     keyEnd();
  389. #ifdef COPY_PASTE
  390.     editEnd();
  391. #endif /* COPY_PASTE */
  392. #ifdef SOFT_FONT
  393.     fontEnd();
  394. #endif
  395. #ifdef FEP
  396.     fep_term();
  397. #endif /* FEP */
  398.     restoreCritHandler();        /* restore critical error handler        */
  399. }
  400.  
  401. void printCompileOptions()
  402. {
  403.     fprintf(stderr, "configured:");
  404. #ifdef SETUP
  405.     fprintf(stderr, " setup");
  406. #endif
  407. #ifdef MOUSE
  408.     fprintf(stderr, " mouse");
  409. #endif
  410. #ifdef BS_WATCHER
  411.     fprintf(stderr, " BS-Key-Watcher");
  412. #endif
  413. #ifdef KERMIT
  414.     fprintf(stderr, " kermit");
  415. #endif
  416. #ifdef XMODEM
  417.     fprintf(stderr, " x/ymodem");
  418. #endif
  419. #ifdef COPY_PASTE
  420.     fprintf(stderr, " history");
  421. #endif
  422. #ifdef SOFT_FONT
  423.     fprintf(stderr, " soft-font");
  424. #endif
  425. #ifdef NEC_KANJI
  426.     fprintf(stderr, " NEC-kanji");
  427. #endif
  428. #ifdef UOP_GRAPHICS
  429.     fprintf(stderr, " graphics");
  430. #endif
  431. #ifdef ICO_SAVER
  432.     fprintf(stderr, " ico-screen-saver");
  433. #endif
  434. #ifdef OVERLAY
  435.     fprintf(stderr, " overlay");
  436. #endif
  437.     fprintf(stderr, "\nnot configured:");
  438. #ifndef SETUP
  439.     fprintf(stderr, " setup");
  440. #endif
  441. #ifndef MOUSE
  442.     fprintf(stderr, " mouse");
  443. #endif
  444. #ifndef BS_WATCHER
  445.     fprintf(stderr, " BS-Key-Watcher");
  446. #endif
  447. #ifndef KERMIT
  448.     fprintf(stderr, " kermit");
  449. #endif
  450. #ifndef XMODEM
  451.     fprintf(stderr, " x/ymodem");
  452. #endif
  453. #ifndef COPY_PASTE
  454.     fprintf(stderr, " history");
  455. #endif
  456. #ifndef SOFT_FONT
  457.     fprintf(stderr, " soft-font");
  458. #endif
  459. #ifndef NEC_KANJI
  460.     fprintf(stderr, " NEC-kanji");
  461. #endif
  462. #ifndef UOP_GRAPHICS
  463.     fprintf(stderr, " graphics");
  464. #endif
  465. #ifndef ICO_SAVER
  466.     fprintf(stderr, " ico-screen-saver");
  467. #endif
  468. #ifndef OVERLAY
  469.     fprintf(stderr, " overlay");
  470. #endif
  471.     fprintf(stderr, "\n");
  472. }
  473.  
  474. /*
  475. ** options(int argc, char **argv)
  476.  *
  477.  * parse command line options
  478.  */
  479. static void options(argc, argv)
  480. char **argv;
  481. {
  482.     register char *p;
  483.  
  484.     setFileName[0] = '\0';        /* default no set file    */
  485.     setupSpecified = NO;
  486.  
  487. nextopt:
  488.     while (--argc > 0)
  489.         if (*(p = *++argv) == '-')
  490.             for (++p; *p; p++)
  491.                 switch(tolower(*p)) {
  492. #ifdef PC98
  493.                 case 'a': optAsckey = YES; break;
  494.                 case 'p': optAsckey = NO; break;
  495. #endif /* PC98 */
  496.                 case 'b': optBaudrate = atol(++p); 
  497.                     if (baudNum((u_short)optBaudrate) == -1) {
  498.                         cant();
  499.                         fprintf(stderr, msg_baudrate, optBaudrate);
  500. #ifdef PC98                                /* funny baudrate %ld    */
  501.                         fprintf(stderr, msg_pc98baud);
  502. #endif /* PC98 */                        /* up to 9600 baud on 8/16Mhz PC9801 */
  503.                         exit(1);
  504.                     }
  505.                     goto nextopt;
  506.                 case 'd': optRedial = DIAL_STATE_START; break;
  507.                 case 'n': 
  508.                     switch (*++p) {
  509.                     case 'd': optRedial = DIAL_STATE_NONE;
  510.                           break;
  511.                     case 's': optNoSetup = YES; break;
  512.                     default:
  513.                       cant(); exit(1);
  514.                     }
  515.                     break;
  516.                 case 'l': optPortNo = atoi(++p) - PORT_BASE;
  517.                     if (optPortNo < 0 || optPortNo > MAX_PORT) {
  518.                         cant();
  519.                         fprintf(stderr, "port com%d: is not supported\n", optPortNo);
  520.                         exit(1);
  521.                     }
  522.                     goto nextopt;
  523. #ifdef SOFT_FONT
  524.                 case 'f': 
  525.                     optSoftFont++;
  526.                     if (*++p)
  527.                         optFontName = p;
  528.                     goto nextopt;
  529. #else
  530.                 case 'f':
  531.                     cant();
  532.                     fprintf(stderr, "Soft font not configured\n");
  533.                     exit(1);
  534. #endif /* SOFT_FONT */
  535.                 case 'h':
  536.                 case '?': cant(); exit(0);
  537.                 default: cant();
  538.                     fprintf(stderr, "unknown option '%c'.\n", *p);
  539.                     exit(1);
  540.                 }
  541.         else {
  542.             setFile = *argv;
  543.             setupSpecified = YES;
  544.         }
  545. }
  546.  
  547. /*
  548. ** static void cant()
  549.  *
  550.  * print version string and invocation options
  551.  */
  552. static void cant()
  553. {
  554.     fprintf(stderr, versionString());
  555.     fprintf(stderr, helpmsg);
  556.     fprintf(stderr, machineOption);
  557.     printCompileOptions();
  558.     fprintf(stderr, "\n");
  559. }
  560.  
  561. /*
  562. ** static void doDial(short c)
  563.  *
  564.  * simple state machine for auto dialing and login
  565.  * You need this, haan?   Yes, I want this. :-)
  566.  */
  567. static void doDial(c)
  568. short c;
  569. {
  570.     static char *scriptPtr;
  571.     static dialPause = DIAL_DELAY;
  572.  
  573.     if (redial == DIAL_STATE_START) {
  574.         putComment("dialing...", msg_null);
  575.         kermitTimer = timerLoadValue;
  576.         scriptPtr = phone; redial = DIAL_STATE_PUT;
  577.     }
  578.     if (redial != DIAL_STATE_WAIT && (timerLoadValue - kermitTimer <= dialPause))
  579.         return;
  580.     kermitTimer = timerLoadValue;
  581.     if (dialPause != DIAL_DELAY)    /* end pause        */
  582.         dialPause = DIAL_DELAY;
  583.     switch (redial) {
  584.     case DIAL_STATE_PUT:
  585.         switch (*scriptPtr) {
  586.         case 0:        /* end of script    */
  587.             redial = DIAL_STATE_NONE;
  588.             conPrint("\r\n");
  589.             putComment("dialing end", msg_null);
  590.             time(&starTime);
  591.             break;
  592.         case DIAL_BEGIN_WAIT_CHAR:
  593.             redial = DIAL_STATE_WAIT;
  594.             scriptPtr++;
  595.             break;
  596.         case DIAL_PAUSE_CHAR:
  597.             scriptPtr++;
  598.             if (isdigit(*scriptPtr))
  599.                 dialPause = atoi(scriptPtr++) * TICK_SEC;
  600.             else
  601.                 dialPause = DEFAULT_DIAL_PAUSE * TICK_SEC;
  602.             break;
  603.         default:    /* ordinary characters    */
  604.             outPort(*scriptPtr++);
  605.             break;
  606.         }
  607.         break;
  608.     case DIAL_STATE_WAIT:    /* template matching    */
  609.         if (c != -1 && ((c & cMask) == *scriptPtr || *scriptPtr == '?'))
  610.             scriptPtr++;
  611.         if (*scriptPtr == 0)
  612.             redial = DIAL_STATE_PUT;
  613.         else if (*scriptPtr == DIAL_END_WAIT_CHAR) {
  614.             scriptPtr++;
  615.             redial = DIAL_STATE_PUT;
  616.         }
  617.         break;
  618.     }
  619. }
  620.  
  621. /* 
  622. ** static void htermCtrl(u_short c)
  623.  *
  624.  * hterm control by special key or mouse
  625.  * upper 8 bit of c is special code
  626.  */
  627. static void htermCtrl(c)
  628. u_short c;
  629. {
  630.     extern char *sge_lineMode[];    /* in setup.c    */
  631.     extern char *sc_baud;        /* in setup.c    */
  632.     extern char *sc_par[];        /* in setup.c    */
  633.  
  634.     switch (c) {
  635.     /*
  636.      * setup, exit
  637.      */
  638.     case META_PF10:
  639.     case STOP_KEY: termination();break;    /* exit hterm     */
  640.     case META_PF9:
  641.     case SETUP_KEY: 
  642. #ifdef SETUP
  643.         setup(); break;        /* set-up mode    */
  644. #else
  645.         putComment("Set-up not configured", msg_null);
  646.         break;
  647. #endif /* SETUP */
  648.  
  649.     /*
  650.      * CTRL-PF: hterm control
  651.      */
  652.     case PF_CLEAR_TEXT:     /* clear text screen    */
  653.         attrib = eraseAttr;
  654.         initPage();
  655.         clearSavedPage(ansiVramSave);
  656.         break;
  657.     case PF_CLEAR_GRAPHIC:    /* clear graphic screen    */
  658. #ifdef UOP_GRAPHICS
  659.         plot_erase();
  660. #endif /* UOP_GRAPHICS */
  661.         break;
  662.     case PF_LINE_MODE:     /* 19line/20line/24line/25line mode    */
  663.         if (++lineMode > MAX_LINE_MODE) lineMode = 0;
  664.         setLineMode(lineMode);
  665.         lowScrRegion = bottomLine;
  666.         initPage();
  667.         cursorOnOff(cursor);
  668.         flushComment(sge_lineMode[lineMode]);
  669.         break;
  670. #ifdef COPY_PASTE
  671.     case PF_PASTE:
  672.         paste();
  673.         break;
  674.     case PF_HIST_EDIT:
  675.         historyEditor();
  676.         break;
  677. #else
  678.     case PF_PASTE:
  679.     case PF_HIST_EDIT:
  680.         putComment("history not configured", msg_null);
  681.         break;
  682. #endif /* COPY_PASTE */
  683.     case PF_REDIAL:     /* send dialing sequence    */
  684.         redial = DIAL_STATE_START;
  685.         break;
  686.     case PF_BAUD:     /* change baud rate    */
  687.         baud++; if (baud > BAUD_NUM_MAX) baud = 1;
  688.         if (numBaud(baud) == 0)
  689.             baud = 1;
  690.         initPortDevice(baud, parity);
  691.         baudrate = numBaud(baud);
  692.         sprintf(tmpBuf, sc_baud, numBaud(baud));
  693.         flushComment(tmpBuf);
  694.         break;
  695.     case PF_PARITY:     /* change parity/stop bit */
  696.         paritybit++; if (paritybit > MAX_PARITY) paritybit = 0;
  697.         parity = parcalc(paritybit, stopbit);
  698.         initPortDevice(baud, parity);
  699.         flushComment(sc_par[paritybit]);
  700.         break;
  701.     case PF_LOGGING:          /* logging on/off    */
  702.         setLogging(); break;
  703.     case PF_UPLOAD:            /* up load        */
  704.         setUpLoad(); break;
  705.     case PF_CHDIR:            /* META_PF1: change directory    */
  706.         changeDirectory(); break;
  707. #ifdef XMODEM
  708.     case PF_XMODEM_REC:        /* META_PF2: xmodem receive        */
  709.         xrec(); break;
  710.     case PF_XMODEM_SEND:    /* META_PF3: xmodem send        */
  711.         xsend(); break;
  712. #else
  713.     case PF_XMODEM_REC:        /* META_PF2: xmodem receive        */
  714.     case PF_XMODEM_SEND:    /* META_PF3: xmodem send        */
  715.         putComment("xmodem not configured", msg_null);
  716.         break;
  717. #endif /* XMODEM */
  718. #ifdef KERMIT
  719.     case PF_KERM_REC:        /* META_PF4: kermit receive        */
  720.         krec(); break;
  721.     case PF_KERM_SEND:        /* META_PF5: kermit send        */
  722.         ksend(); break;
  723.     case PF_KERM_GET:        /* META_PF6: (optional) kermit get        */
  724.         kget(); break;
  725.     case PF_KERM_FINISH:    /* META_PF7: (optional) kermit finish    */
  726.         kfinish(); break;
  727. #else
  728.     case PF_KERM_REC:        /* META_PF4: kermit receive        */
  729.     case PF_KERM_SEND:        /* META_PF5: kermit send        */
  730.     case PF_KERM_GET:        /* META_PF6: (optional) kermit get        */
  731.     case PF_KERM_FINISH:    /* META_PF7: (optional) kermit finish    */
  732.         putComment("kermit not configured", msg_null);
  733.         break;
  734. #endif /* KERMIT */
  735.     case PF_CALL_OS:        /* META_PF8: (optional) call OS    */
  736.         showPage1();
  737.         callOS();
  738.         showPage0();
  739.         break;
  740.     /* META PF6-PF8 are reserved for users. */
  741.     /*         You can use these keys freely. */
  742.     /*        See config.h and search PF_USER    */
  743.     /* META PF9-PF10 are used by hterm for IBM-PC set-up and exit */
  744.     }
  745. }
  746.  
  747. #ifdef BS_WATCHER
  748. /* #define BS_DEBUG */
  749. /*
  750.  * BS key watcher
  751.  *
  752.  * 'Hey, take a rest!' message will appear if
  753.  *
  754.  *    1) bsKeyRatio is not zero, and
  755.  *    2) SAMPLING_TIME is over, and
  756.  *    3) not reached SAMPLING_TIME+60 sec, and
  757.  *    4) at least INTERVAL_TIME sec is over from last message, and
  758.  *    5) total key count is over THRESH_KEY, and
  759.  *    6) BS/total ratio is over bsKeyRatio
  760.  */ 
  761. static void bsKeyWatcher()
  762. {
  763.     static time_t lasTime = 0;    /* This means first call always fails */
  764.     static time_t lastMsgTime = 0;
  765.     time_t curTime;
  766.     struct tm *curLocalTime;
  767.     int ratio;
  768.  
  769.     time(&curTime);
  770.     if ((curTime- lasTime) > BS_WATCHER_SAMPLING_TIME + 60) {
  771. #ifdef BS_DEBUG
  772.         conPrint("too long absense");
  773. #endif
  774.         /* First call of bsKeyWatcher() always fails */
  775.         keyCount = 0;        /* too long absense    */
  776.     }
  777.     bsKeyWatcherTimer = BS_WATCHER_SAMPLING_TIME*TICK_SEC;
  778.     lasTime = curTime;
  779.  
  780.     /*
  781.      * if last message was too near, return
  782.      */
  783.     if ((curTime - lastMsgTime) < BS_WATCHER_INTERVAL_TIME) {
  784. #ifdef BS_DEBUG
  785.         sprintf(tmpBuf, "diftime %d", (int)difftime(curTime, lasTime));
  786.         conPrint(tmpBuf);
  787. #endif
  788.         bsKeyCount = keyCount = 0;    
  789.         return;
  790.     }
  791.  
  792.     if (keyCount < BS_WATCHER_THRESH_KEY) {
  793.         bsKeyCount = keyCount = 0;
  794.         return;
  795.     }
  796.  
  797.     ratio = (bsKeyCount*100)/keyCount;
  798.  
  799.     /*
  800.      * if too many BS keys were not typed.
  801.      */
  802.     if (ratio < bsKeyRatio) {
  803. #ifdef BS_DEBUG
  804.         sprintf(tmpBuf, "ratio %d", ratio);
  805.         conPrint(tmpBuf);
  806. #endif
  807.         bsKeyCount = keyCount = 0;    
  808.         return;
  809.     }
  810.  
  811.     showPage1();            /* save page0 and show page 1    */
  812.  
  813.     /*
  814.      * select proper message
  815.      */    
  816.     curLocalTime = localtime(&curTime);
  817.     if (8 <= curLocalTime->tm_hour && curLocalTime->tm_hour < 12) {
  818.         sprintf(tmpBuf, "morning %u", (int)curTime % 3);
  819.     } else if (0 <= curLocalTime->tm_hour && curLocalTime->tm_hour < 7) {
  820.         sprintf(tmpBuf, "sleep %u", (int)curTime % 3);
  821.     } else {
  822.         sprintf(tmpBuf, "coffee %u", (int)curTime % 3);
  823.     }
  824.     /*
  825.      * pick it up, display
  826.      */
  827.     bell();
  828.     (void)helpSystem(tmpBuf);
  829.     sprintf(tmpBuf, "\tLast %d minutes key count %d, BS/DEL key %d (%d%%)", 
  830.         BS_WATCHER_SAMPLING_TIME/60,
  831.         keyCount, bsKeyCount, ratio);
  832.     conPrint(tmpBuf);
  833.     /*
  834.      * show message for short time
  835.      */
  836.     bsKeyWatcherTimer = BS_WATCHER_MESSAGE_TIME*TICK_SEC;
  837.     while (bsKeyWatcherTimer > 0) {
  838. #if 0
  839.         if (checkEvent())
  840.             break;
  841. #endif
  842.         nullFunction();
  843.     }
  844.     bell();
  845.     showPage0();
  846.     /*
  847.      * prepare for next time
  848.      */
  849.     bsKeyWatcherTimer = BS_WATCHER_SAMPLING_TIME*TICK_SEC;
  850.     bsKeyCount = keyCount = 0;    
  851.     lastMsgTime = curTime;
  852. }
  853. #endif /* BS_WATCHER */
  854.