home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / LINEconsole / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  10.9 KB  |  545 lines

  1. /* io.c: i/o routines for linebased console */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/io.c,v 6.0 1991/12/18 20:26:30 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/io.c,v 6.0 1991/12/18 20:26:30 jpo Rel $
  9.  *
  10.  * $Log: io.c,v $
  11.  * Revision 6.0  1991/12/18  20:26:30  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15. #include    "console.h"
  16. #include    <signal.h>
  17.  
  18. /*   */
  19. /* paging routines */
  20.  
  21. char     *cmd_argv[100];
  22. int    cmd_argc;
  23.     
  24. char    *pager;
  25. FILE    *out;
  26. extern FILE *popen ();
  27. SFP     oldpipe;
  28. int    pipeopen, pageron, fileopen;
  29.  
  30. init_pager()
  31. {
  32.     if ((pager = getenv("PAGER")) == NULL)
  33.         pager = strdup("more");
  34.     else 
  35.         pager = strdup(pager);
  36.     pageron = TRUE;
  37. }
  38.  
  39. /* ARGSUSED */
  40. static void piped(sig)
  41. int sig;
  42. {
  43.         pipeopen = 0;
  44. }
  45.  
  46. void openpager()
  47. {
  48.     FILE    *fp;
  49.     fileopen = FALSE;
  50.     if (cmd_argc > 1) {
  51.         int    i;
  52.         for (i = 1; i < cmd_argc; i++) {
  53.             if (lexequ(cmd_argv[i], ">") == 0
  54.                 || lexequ(cmd_argv[i], ">>") == 0) {
  55.                 int    append = (lexequ(cmd_argv[i], ">") == 0) ? FALSE : TRUE;
  56.                 i++;
  57.                 if (i >= cmd_argc)
  58.                     fprintf(stderr,
  59.                         "redirect argument (%s) given but no destination specified\n",
  60.                         cmd_argv[i-1]);
  61.                 else if ((fp = fopen(cmd_argv[i], 
  62.                              (append == TRUE) ? "a" : "w")) == NULL)
  63.                     fprintf(stderr,
  64.                         "unable to open redirect destination '%s' for %s\n",
  65.                         cmd_argv[i],
  66.                         (append == TRUE) ? "appending" : "writing");
  67.                 else {
  68.                     fileopen = TRUE;
  69.                     out = fp;
  70.                     i = cmd_argc;
  71.                 }
  72.             } 
  73.         }
  74.     }
  75.     
  76.     if (fileopen == TRUE)
  77.         return;
  78.  
  79.     if (pageron == TRUE) {
  80.         oldpipe = signal(SIGPIPE, piped);
  81.         if (isatty(1) == 0
  82.             || pager == NULLCP)
  83.             out = stdout;
  84.         else if ((out = popen(pager,"w")) == NULL) {
  85.             fprintf(stderr, "unable to start pager '%s': %s\n",
  86.                 pager, sys_errname (errno));
  87.             out = stdout;
  88.         }
  89.         pipeopen = 1;
  90.     } else
  91.         out = stdout;
  92. }
  93.  
  94. void closepager()
  95. {
  96.         if (out != stdout) {
  97.         if (fileopen == TRUE)
  98.             fclose(out);
  99.         else
  100.             pclose(out);
  101.                 out = stdout;
  102.         }
  103.         pipeopen = 0;
  104.     if (pageron == TRUE)
  105.         signal(SIGPIPE, oldpipe);
  106. }
  107.  
  108. /*   */
  109. /* routine to read in commands */
  110. static CMD_TABLE    tb_commands [] = { /* all possible commands */
  111.     "aboveclear",    (int) AboveClear,
  112.     "aboveclea",    (int) AboveClear,
  113.     "abovecle",    (int) AboveClear,
  114.     "abovecl",    (int) AboveClear,
  115.     "abovec",    (int) AboveClear,
  116.     "above",    (int) AboveClear,
  117.     "abov",        (int) AboveClear,
  118.     "abo",        (int) AboveClear,
  119.     "ab",        (int) AboveClear,
  120.     "a",        (int) AboveClear,
  121.  
  122.     "belowclear",    (int) BelowClear,
  123.     "belowclea",    (int) BelowClear,
  124.     "belowcle",    (int) BelowClear,
  125.     "belowcl",    (int) BelowClear,
  126.     "belowc",    (int) BelowClear,
  127.     "below",    (int) BelowClear,
  128.     "belo",        (int) BelowClear,
  129.     "bel",        (int) BelowClear,
  130.     "be",        (int) BelowClear,
  131.     "b",        (int) BelowClear,
  132.  
  133.  
  134.     "clear",    (int) Clear,
  135.     "clea",        (int) Clear,
  136.     "cle",        (int) Clear,
  137.     "cl",        (int) Clear,
  138.  
  139.     "connect",    (int) Connect,
  140.     "connec",    (int) Connect,
  141.     "conne",    (int) Connect,
  142.     "conn",        (int) Connect,
  143.     "con",        (int) Connect,
  144.     "co",        (int) Connect,
  145.  
  146.     "current",    (int) Current,
  147.     "curren",    (int) Current,
  148.     "curre",    (int) Current,
  149.     "curr",        (int) Current,
  150.     "cur",        (int) Current,
  151.     "cu",        (int) Current,
  152.  
  153.     "c",        (int) Ambiguous,
  154.  
  155.     "delay",    (int) Delay,
  156.     "dela",        (int) Delay,
  157.     "del",        (int) Delay,
  158.     "de",        (int) Delay,
  159.  
  160.     "disable",    (int) Disable,
  161.     "disabl",    (int) Disable,
  162.     "disab",    (int) Disable,
  163.     "disa",        (int) Disable,
  164.     
  165.     "disconnect",     (int) Disconnect,
  166.     "disconnec",     (int) Disconnect,
  167.     "disconne",     (int) Disconnect,
  168.     "disconn",     (int) Disconnect,
  169.     "discon",     (int) Disconnect,
  170.     "disco",     (int) Disconnect,
  171.     "disc",     (int) Disconnect,
  172.  
  173.     "dis",        (int) Ambiguous,
  174.  
  175.     "down",        (int) Down,
  176.     "dow",        (int) Down,
  177.     "do",        (int) Down,
  178.     
  179.     "d",        (int) Ambiguous,
  180.  
  181.     "enable",    (int) Enable,
  182.     "enabl",    (int) Enable,
  183.     "enab",        (int) Enable,
  184.     "ena",        (int) Enable,
  185.     "en",        (int) Enable,
  186.     "e",        (int) Enable,
  187.  
  188.     "heuristics",    (int) Heuristics,
  189.     "heuristic",    (int) Heuristics,
  190.     "heuristi",    (int) Heuristics,
  191.     "heurist",    (int) Heuristics,
  192.     "heuris",    (int) Heuristics,
  193.     "heuri",    (int) Heuristics,
  194.     "heur",        (int) Heuristics,
  195.     "heu",        (int) Heuristics,
  196.     "he",        (int) Heuristics,
  197.     "h",        (int) Heuristics,
  198.  
  199.     "informatio",    (int) Info,
  200.     "informati",    (int) Info,
  201.     "informat",    (int) Info,
  202.     "informa",    (int) Info,
  203.     "inform",    (int) Info,
  204.     "infor",    (int) Info,
  205.     "info",        (int) Info,
  206.     "inf",        (int) Info,
  207.     "in",        (int) Info,
  208.     "i",        (int) Info,
  209.  
  210.  
  211.     "list",        (int) List,
  212.     "lis",        (int) List,
  213.     "li",        (int) List,
  214.     "l",        (int) List,
  215.  
  216.     "next",        (int) Next,
  217.     "nex",        (int) Next,
  218.     "ne",        (int) Next,
  219.     "n",        (int) Next,
  220.  
  221.     "previous",    (int) Previous,
  222.     "previou",    (int) Previous,
  223.     "previo",    (int) Previous,
  224.     "previ",    (int) Previous,
  225.     "prev",        (int) Previous,
  226.     "pre",        (int) Previous,
  227.     "pr",        (int) Previous,
  228.     "p",        (int) Previous,
  229.  
  230.     "quecontrol",    (int) Quecontrol,
  231.     "quecontro",    (int) Quecontrol,
  232.     "quecontr",    (int) Quecontrol,
  233.     "quecont",    (int) Quecontrol,
  234.     "quecon",    (int) Quecontrol,
  235.     "queco",    (int) Quecontrol,
  236.     "quec",        (int) Quecontrol,
  237.     "que",        (int) Quecontrol,
  238.  
  239.     
  240.     "quit",        (int) Quit,
  241.     "qui",        (int) Quit,
  242.     
  243.     "qu",        (int) Ambiguous,
  244.     "q",        (int) Ambiguous,
  245.  
  246.     "refresh",    (int) Refresh,
  247.     "refres",    (int) Refresh,
  248.     "refre",    (int) Refresh,
  249.     "refr",        (int) Refresh,
  250.     "ref",        (int) Refresh,
  251.     "re",        (int) Refresh,
  252.     "r",        (int) Refresh,
  253.     
  254.     "status",    (int) Status,
  255.     "statu",    (int) Status,
  256.     "stat",        (int) Status,
  257.     "sta",        (int) Status,
  258.     "st",        (int) Status,
  259.  
  260.     "set",        (int) Set,
  261.     "se",        (int) Set,
  262.  
  263.     "s",        (int) Ambiguous,
  264.  
  265.     "up",        (int) Up,
  266.     "u",        (int) Up,
  267.  
  268.     "unknown",    (int) Unknown,
  269.     0,        -1
  270.     };
  271.  
  272. Command str2command();
  273. char    *level2str();
  274. void    command_options();
  275. extern int    connected;
  276. extern int    authorised;
  277. extern char    *host;
  278. extern Command    comm;
  279. extern Level    lev;
  280. extern struct chan_struct    *currentchan;
  281. extern struct mta_struct    *currentmta;
  282. char    prompt[BUFSIZ];
  283.  
  284. extern char    *chan_match, *mta_match, *msg_match;
  285.  
  286. reset_prompt_regex()
  287. {
  288.     switch(lev) {
  289.         case top:
  290.         sprintf(prompt, "%s", level2str(lev));
  291.         break;
  292.         case channel:
  293.         sprintf(prompt, "%s", 
  294.             (chan_match) ? chan_match : level2str(lev));
  295.         break;
  296.         case mta:
  297.         sprintf(prompt, "%s.%s",
  298.             (currentchan) ? currentchan->channelname : level2str(channel),
  299.             (mta_match) ? mta_match : level2str(lev));
  300.         break;
  301.         case msg:
  302.         sprintf(prompt, "%s.%s.%s",
  303.             (currentchan) ? currentchan->channelname : level2str(channel),
  304.             (currentmta) ? currentmta->mta : level2str(mta),
  305.             (msg_match) ? msg_match : level2str(lev));
  306.         break;
  307.     }
  308. }
  309.  
  310. int    info_shown;
  311.  
  312. static void set_info(com)
  313. Command    com;
  314. {
  315.     switch(com) {
  316.         case Info:
  317.         case Next:
  318.         case Previous:
  319.         info_shown = TRUE;
  320.         case Refresh:
  321.         case Heuristics:
  322.         case Status:
  323.         break;
  324.         default:
  325.         info_shown = FALSE;
  326.         break;
  327.     }
  328. }
  329.  
  330. Command    get_command(lev)
  331. Level    lev;
  332. {
  333.     Command    ret = Unknown;
  334.     int    cont = TRUE;
  335.     static  char    buf[BUFSIZ];
  336.     cmd_argc = 0;
  337.     while (cont == TRUE) {
  338.         fprintf(stdout, "%s> ", prompt);
  339.         fflush (stdout);
  340.         
  341.         if (gets(buf) == NULL)
  342.             exit(OK);
  343.         (void) compress(buf, buf);
  344.         
  345.         cmd_argc = sstr2arg(buf, 100, cmd_argv, " \t");
  346.  
  347.         if (cmd_argc == 0) {
  348.             /* use same command as before */
  349.             ret = comm;
  350.             cont = FALSE;
  351.         } else if ((ret = str2command(cmd_argv[0])) == Unknown) {
  352.             fprintf(stdout,
  353.                 "Unknown command '%s'\n", cmd_argv[0]);
  354.             command_options(lev);
  355.         } else if (ret == Ambiguous) {
  356.             fprintf(stdout,
  357.                 "Ambiguous command '%s'\n", cmd_argv[0]);
  358.             command_options(lev);
  359.             ret = Unknown;
  360.         } else if (check_command(ret, lev) == NOTOK) {
  361.             fprintf(stdout,
  362.                 "Command '%s' unavailable at '%s' level\n",
  363.                 command2str(ret), level2str(lev));
  364.             command_options(lev);
  365.         } else if (ret == Connect && connected == TRUE) 
  366.             fprintf(stdout,
  367.                 "Already connected (to %s)\n", host);
  368.         else if (ret == Disconnect && connected == FALSE)
  369.             fprintf(stdout,
  370.                 "Already unconnected\n");
  371.         else
  372.             cont = FALSE;
  373.     }
  374.     set_info(ret);
  375.     return ret;
  376. }
  377.  
  378. /*   */
  379. /* command recognition routines */
  380.  
  381. Command    str2command(str)
  382. char    *str;
  383. {
  384.     Command    ret;
  385.     
  386.     if ((ret = (Command) cmd_srch(str, tb_commands)) == -1)
  387.         ret = Unknown;
  388.     return ret;
  389. }
  390.  
  391. char *command2str(com)
  392. Command    com;
  393. {
  394.     return rcmd_srch(com, tb_commands);
  395. }
  396.  
  397. int check_command(com, lev)
  398. Command    com;
  399. Level    lev;
  400. {
  401.     switch(lev) {
  402.         case top:
  403.         switch(com) {
  404.             case Connect:
  405.             case Disconnect:
  406.             case Heuristics:
  407.             case Quit:
  408.             case Status:
  409.             case Set:
  410.             return OK;
  411.             default:
  412.             return NOTOK;
  413.         }
  414.         case channel:
  415.         switch(com) {    
  416.             case Disconnect:
  417.             case Down:
  418.             case Heuristics:
  419.             case Quit:
  420.             case List:
  421.             case Current:
  422.             case Info:
  423.             case Next:
  424.             case Previous:
  425.             case Refresh:
  426.             case Status:
  427.             case Set:
  428.             return OK;
  429.             case Enable:
  430.             case Disable:
  431.             case Delay:
  432.             case Clear:
  433.             case BelowClear:
  434.             case Quecontrol:
  435.             if (authorised == TRUE)
  436.                 return OK;
  437.             default:
  438.             return NOTOK;
  439.         }
  440.         case mta:
  441.         switch(com) {    
  442.             case Disconnect:
  443.             case Down:
  444.             case Up:
  445.             case Heuristics:
  446.             case Quit:
  447.             case List:
  448.             case Current:
  449.             case Info:
  450.             case Next:
  451.             case Previous:
  452.             case Refresh:
  453.             case Status:
  454.             case Set:
  455.             return OK;
  456.             case Enable:
  457.             case Disable:
  458.             case Delay:
  459.             case Clear:
  460.             case BelowClear:
  461.             case AboveClear:
  462.             case Quecontrol:
  463.             if (authorised == TRUE)
  464.                 return OK;
  465.             default:
  466.             return NOTOK;
  467.         }
  468.         case msg:
  469.         switch(com) {    
  470.             case Disconnect:
  471.             case Up:
  472.             case Heuristics:
  473.             case Quit:
  474.             case List:
  475.             case Current:
  476.             case Info:
  477.             case Next:
  478.             case Previous:
  479.             case Refresh:
  480.             case Status:
  481.             case Set:
  482.             return OK;
  483.             case Enable:
  484.             case Disable:
  485.             case Delay:
  486.             case Clear:
  487.             case AboveClear:
  488.             case Quecontrol:
  489.             if (authorised == TRUE)
  490.                 return OK;
  491.             default:
  492.             return NOTOK;
  493.         }
  494.         default:
  495.         return NOTOK;
  496.     }
  497. }
  498.  
  499. void command_options(lev)
  500. Level    lev;
  501. {
  502.     fprintf(stdout,
  503.         "Commands available are:");
  504.     switch(lev) {
  505.         case top:
  506.         fprintf(stdout,
  507.             "connect, disconnect, quit, status, set\n\tand heuristics\n");
  508.         break;
  509.         case channel:
  510.         fprintf(stdout,
  511.             "disconnect, quit, current, status, set, refresh\n\tdown, next, previous, list, info%sand heuristics\n",
  512.             (authorised == TRUE) ? ",\n\tenable, disable, delay, clear\n\tbelowclear, quecontrol " : " ");
  513.         break;
  514.         case mta:
  515.         fprintf(stdout,
  516.             "disconnect, quit, current, status, set, refresh\n\tdown, up, next, previous, list, info%sand heuristics\n",
  517.             (authorised == TRUE) ? ",\n\tenable, disable, delay, clear\n\tbelowclear, aboveclear, quecontrol " : " ");
  518.         break;
  519.         case msg:
  520.         fprintf(stdout,
  521.             "disconnect, quit, current, status, set, refresh\n\tup, next, previous, list, info%sand heuristics\n",
  522.             (authorised == TRUE) ? ",\n\tenable, disable, delay, clear\n\taboveclear, quecontrol " : " ");
  523.         break;
  524.     }
  525. }
  526.  
  527. /*   */
  528. /* level manipulation routines */
  529.  
  530. char *level2str(lev)
  531. Level    lev;
  532. {
  533.     switch(lev) {
  534.         case top:
  535.         return "top";
  536.         case channel:
  537.         return "channel";
  538.         case mta:
  539.         return "mta";
  540.         case msg:
  541.         return "msg";
  542.     }
  543.     return "";
  544. }
  545.