home *** CD-ROM | disk | FTP | other *** search
/ Informática Multimedia: Special Games (Alt) / INFESPGAMES.iso / os2 / backgam / source / command1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-25  |  15.9 KB  |  543 lines

  1. /*************************************************************
  2.  *    ______                                                 *
  3.  *   /     /\  TinyFugue was derived from a client initially *
  4.  *  /   __/  \ written by Anton Rang (Tarrant) and later     *
  5.  *  |  / /\  | modified by Leo Plotkin (Grod).  The early    *
  6.  *  |  |/    | versions of TinyFugue written by Greg Hudson  *
  7.  *  |  X__/  | (Explorer_Bob).  The current version is       *
  8.  *  \ /      / written and maintained by Ken Keys (Hawkeye), *
  9.  *   \______/  who can be reached at kkeys@ucsd.edu.         *
  10.  *                                                           *
  11.  *             No copyright 1992, no rights reserved.        *
  12.  *             Fugue is in the public domain.                *
  13.  *************************************************************/
  14.  
  15. /*****************************************************************
  16.  * Fugue command handlers, part 1                                *
  17.  *                                                               *
  18.  * Contents:                                                     *
  19.  * 1. Command table and declarations                             *
  20.  * 2. Binary search/execute routines, macro handlers             *
  21.  * 3. Command handlers:                                          *
  22.  *     A. Help subsystem                                         *
  23.  *     B. Worlds                                                 *
  24.  *     C. Processes (/quote and /repeat and related commands)    *
  25.  *     D. Watchdog routines                                      *
  26.  *     E. Miscellaneous routines                                 *
  27.  *                                                               *
  28.  * The other module contains flag and numeric runtime option     *
  29.  * handers, and all string-processing subsystem command (macros, *
  30.  * triggers, hilites, and gags).                                 *
  31.  *                                                               *
  32.  *****************************************************************/
  33.  
  34. #include <stdio.h>
  35. #include <signal.h>
  36. #include <ctype.h>
  37. #include "tf.h"
  38. #include "dstring.h"
  39. #include "util.h"
  40. #include "history.h"
  41. #include "world.h"
  42. #include "socket.h"
  43. #include "output.h"
  44. #include "macro.h"
  45. #include "help.h"
  46. #include "process.h"
  47. #include "keyboard.h"
  48.  
  49. extern int visual;
  50. extern int board;
  51.  
  52. Handler *FDECL(find_command,(char *cmd));
  53. static void FDECL(handle_macro_command,(char *cmd, char *args));
  54.  
  55. void FDECL(handle_command,(char *cmdline, Stringp dest));
  56.  
  57. static HANDLER (handle_addworld_command);
  58. static HANDLER (handle_dc_command);
  59. static HANDLER (handle_echo_command);
  60. static HANDLER (handle_grab_command);
  61. static HANDLER (handle_help_command);
  62. static HANDLER (handle_input_command);
  63. static HANDLER (handle_kill_command);
  64. static HANDLER (handle_lcd_command);
  65. static HANDLER (handle_listsockets_command);
  66. static HANDLER (handle_listworlds_command);
  67. static HANDLER (handle_ps_command);
  68. static HANDLER (handle_purgeworld_command);
  69. static HANDLER (handle_quit_command);
  70. static HANDLER (handle_quote_command);
  71. static HANDLER (handle_recall_command);
  72. static HANDLER (handle_repeat_command);
  73. static HANDLER (handle_saveworld_command);
  74. static HANDLER (handle_send_command);
  75. static HANDLER (handle_sh_command);
  76. static HANDLER (handle_trigger_command);
  77. static HANDLER (handle_unworld_command);
  78. static HANDLER (handle_version_command);
  79. static HANDLER (handle_world_command);
  80. extern HANDLER (handle_background_command);
  81. extern HANDLER (handle_bamf_command);
  82. extern HANDLER (handle_beep_command);
  83. extern HANDLER (handle_bind_command);
  84. extern HANDLER (handle_board_command);
  85. extern HANDLER (handle_borg_command);
  86. extern HANDLER (handle_cat_command);
  87. extern HANDLER (handle_cleardone_command);
  88. extern HANDLER (handle_clearfull_command);
  89. extern HANDLER (handle_def_command);
  90. extern HANDLER (handle_dokey_command);
  91. extern HANDLER (handle_edit_command);
  92. extern HANDLER (handle_gag_command);
  93. extern HANDLER (handle_gpri_command);
  94. extern HANDLER (handle_hilite_command);
  95. extern HANDLER (handle_hook_command);
  96. extern HANDLER (handle_hpri_command);
  97. extern HANDLER (handle_isize_command);
  98. extern HANDLER (handle_kecho_command);
  99. extern HANDLER (handle_list_command);
  100. extern HANDLER (handle_load_command);
  101. extern HANDLER (handle_log_command);
  102. extern HANDLER (handle_login_command);
  103. extern HANDLER (handle_lp_command);
  104. extern HANDLER (handle_lpquote_command);
  105. extern HANDLER (handle_mecho_command);
  106. extern HANDLER (handle_more_command);
  107. extern HANDLER (handle_nogag_command);
  108. extern HANDLER (handle_nohilite_command);
  109. extern HANDLER (handle_ptime_command);
  110. extern HANDLER (handle_purge_command);
  111. extern HANDLER (handle_qecho_command);
  112. extern HANDLER (handle_quiet_command);
  113. extern HANDLER (handle_quitdone_command);
  114. extern HANDLER (handle_redef_command);
  115. extern HANDLER (handle_save_command);
  116. extern HANDLER (handle_shpause_command);
  117. extern HANDLER (handle_sockmload_command);
  118. extern HANDLER (handle_sub_command);
  119. extern HANDLER (handle_trig_command);
  120. extern HANDLER (handle_trigc_command);
  121. extern HANDLER (handle_trigp_command);
  122. extern HANDLER (handle_trigpc_command);
  123. extern HANDLER (handle_unbind_command);
  124. extern HANDLER (handle_undef_command);
  125. extern HANDLER (handle_undefn_command);
  126. extern HANDLER (handle_undeft_command);
  127. extern HANDLER (handle_unhook_command);
  128. extern HANDLER (handle_untrig_command);
  129. extern HANDLER (handle_visual_command);
  130. extern HANDLER (handle_watchdog_command);
  131. extern HANDLER (handle_watchname_command);
  132. extern HANDLER (handle_wrap_command);
  133. extern HANDLER (handle_wrapspace_command);
  134.  
  135. typedef struct Command {
  136.     char *name;
  137.     Handler *func;
  138. } Command;
  139.  
  140.   /* It is IMPORTANT that the commands be in alphabetical order! */
  141.  
  142. static Command cmd_table[] =
  143. {
  144.   { "ADDWORLD"    , handle_addworld_command    },
  145.   { "BACKGROUND"  , handle_background_command  },
  146.   { "BAMF"        , handle_bamf_command        },
  147.   { "BOARD"       , handle_board_command       },
  148.   { "BEEP"        , handle_beep_command        },
  149.   { "BIND"        , handle_bind_command        },
  150.   { "BORG"        , handle_borg_command        },
  151.   { "CAT"         , handle_cat_command         },
  152.   { "CLEARDONE"   , handle_cleardone_command   },
  153.   { "CLEARFULL"   , handle_clearfull_command   },
  154.   { "DC"          , handle_dc_command          },
  155.   { "DEF"         , handle_def_command         },
  156.   { "DOKEY"       , handle_dokey_command       },
  157.   { "ECHO"        , handle_echo_command        },
  158.   { "EDIT"        , handle_edit_command        },
  159.   { "GAG"         , handle_gag_command         },
  160.   { "GPRI"        , handle_gpri_command        },
  161.   { "GRAB"        , handle_grab_command        },
  162.   { "HELP"        , handle_help_command        },
  163.   { "HILITE"      , handle_hilite_command      },
  164.   { "HOOK"        , handle_hook_command        },
  165.   { "HPRI"        , handle_hpri_command        },
  166.   { "INPUT"       , handle_input_command       },
  167.   { "ISIZE"       , handle_isize_command       },
  168.   { "KECHO"       , handle_kecho_command       },
  169.   { "KILL"        , handle_kill_command        },
  170.   { "LCD"         , handle_lcd_command         },
  171.   { "LIST"        , handle_list_command        },
  172.   { "LISTSOCKETS" , handle_listsockets_command },
  173.   { "LISTWORLDS"  , handle_listworlds_command  },
  174.   { "LOAD"        , handle_load_command        },
  175.   { "LOG"         , handle_log_command         },
  176.   { "LOGIN"       , handle_login_command       },
  177.   { "LP"          , handle_lp_command          },
  178.   { "LPQUOTE"     , handle_lpquote_command     },
  179.   { "MECHO"       , handle_mecho_command       },
  180.   { "MORE"        , handle_more_command        },
  181.   { "NOGAG"       , handle_nogag_command       },
  182.   { "NOHILITE"    , handle_nohilite_command    },
  183.   { "PS"          , handle_ps_command          },
  184.   { "PTIME"       , handle_ptime_command       },
  185.   { "PURGE"       , handle_purge_command       },
  186.   { "PURGEWORLD"  , handle_purgeworld_command  },
  187.   { "QECHO"       , handle_qecho_command       },
  188.   { "QUIET"       , handle_quiet_command       },
  189.   { "QUIT"        , handle_quit_command        },
  190.   { "QUITDONE"    , handle_quitdone_command    },
  191.   { "QUOTE"       , handle_quote_command       },
  192.   { "RECALL"      , handle_recall_command      },
  193.   { "REDEF"       , handle_redef_command       },
  194.   { "REPEAT"      , handle_repeat_command      },
  195.   { "SAVE"        , handle_save_command        },
  196.   { "SAVEWORLD"   , handle_saveworld_command   },
  197.   { "SEND"        , handle_send_command        },
  198.   { "SH"          , handle_sh_command          },
  199.   { "SHPAUSE"     , handle_shpause_command     },
  200.   { "SOCKMLOAD"   , handle_sockmload_command   },
  201.   { "SUB"         , handle_sub_command         },
  202.   { "TRIG"        , handle_trig_command        },
  203.   { "TRIGC"       , handle_trigc_command       },
  204.   { "TRIGGER"     , handle_trigger_command     },  
  205.   { "TRIGP"       , handle_trigp_command       },
  206.   { "TRIGPC"      , handle_trigpc_command      },
  207.   { "UNBIND"      , handle_unbind_command      },
  208.   { "UNDEF"       , handle_undef_command       },
  209.   { "UNDEFN"      , handle_undefn_command      },
  210.   { "UNDEFT"      , handle_undeft_command      },
  211.   { "UNHOOK"      , handle_unhook_command      },
  212.   { "UNTRIG"      , handle_untrig_command      },
  213.   { "UNWORLD"     , handle_unworld_command     },
  214.   { "VERSION"     , handle_version_command     },
  215.   { "VISUAL"      , handle_visual_command      },
  216.   { "WATCHDOG"    , handle_watchdog_command    },
  217.   { "WATCHNAME"   , handle_watchname_command   },
  218.   { "WORLD"       , handle_world_command       },
  219.   { "WRAP"        , handle_wrap_command        },
  220.   { "WRAPSPACE"   , handle_wrapspace_command   }
  221. };
  222.  
  223. #define NUM_COMMANDS (sizeof(cmd_table) / sizeof(Command))
  224.  
  225. /*****************************************
  226.  * Find, process and run commands/macros *
  227.  *****************************************/
  228.  
  229. void handle_command(cmd_line, dest)
  230.     char *cmd_line;
  231.     String *dest;
  232. {
  233.     char *cmd, *args;
  234.     Handler *handler;
  235.  
  236.     while (*cmd_line == '/') cmd_line++;
  237.     if (!*cmd_line || isspace(*cmd_line)) return;
  238.     cmd = STRDUP(cmd_line);
  239.     for (args = cmd; *args && !isspace(*args); args++);
  240.     if (*args) *args++ = '\0';
  241.     stripstr(cmd);
  242.     stripstr(args);
  243.     if (handler = find_command(cmd)) (*handler)(args);
  244.     else if (dest == NULL) handle_macro_command(cmd, args);
  245.     else do_macro(cmd, args, dest, 0);
  246.     FREE(cmd);
  247. }
  248.  
  249. Handler *find_command(cmd)
  250.     char *cmd;
  251. {
  252.     int bottom, top, mid, diff;
  253.  
  254.     bottom = 0;
  255.     top = NUM_COMMANDS - 1;
  256.  
  257.     while (bottom <= top) {
  258.         mid = (top + bottom) / 2;
  259.         diff = cstrcmp(cmd, cmd_table[mid].name);
  260.         if (diff == 0) return (cmd_table[mid].func);
  261.         else if (diff < 0) top = mid - 1;
  262.         else bottom = mid + 1;
  263.     }
  264.     return NULL;
  265. }
  266.  
  267. static void handle_macro_command(cmd, args)
  268.     char *cmd;
  269.     char *args;
  270. {
  271.     Stringp expanded;
  272.  
  273.     Stringinit(expanded);
  274.     do_macro(cmd, args, expanded, 1);
  275.     Stringfree(expanded);
  276. }
  277.  
  278. static void handle_trigger_command(args)
  279.     char *args;
  280. {
  281.     extern int borg, background;
  282.  
  283.     if (background) background++;
  284.     if (borg) check_trigger(args);
  285.     if (background) background--;
  286. }
  287.  
  288. static void handle_help_command(args)
  289.     char *args;
  290. {
  291.     do_help(args);
  292. }
  293.  
  294. /**********
  295.  * Worlds *
  296.  **********/
  297.  
  298. static void handle_listworlds_command(args)
  299.     char *args;
  300. {
  301.     int full = FALSE;
  302.     char c;
  303.  
  304.     startopt(args, "c");
  305.     while (c = nextopt(&args, NULL)) {
  306.         switch (c) {
  307.             case 'c':  full = TRUE; break;
  308.             default:   return;
  309.         }
  310.     }
  311.     if (*args && !smatch_check(args)) return;
  312.     list_worlds(full, *args ? args : NULL, NULL);
  313. }
  314.  
  315. static void handle_listsockets_command(args)
  316.     char *args;
  317. {
  318.     if (*args) oputs("% Arguments disregarded.");
  319.     listsockets();
  320. }
  321.  
  322. static void handle_world_command(args)
  323.     char *args;
  324. {
  325.     World *where = NULL;
  326.     int autologin;
  327.     char *port;
  328.     char name[16];          /* big enough for "(unnamedNNNNNN)" */
  329.     static int unnamed = 1;
  330.     extern int login;
  331.  
  332.     autologin = login;
  333.     if (*args == '-') {
  334.         autologin = FALSE;
  335.         args++;
  336.     }
  337.  
  338.     if (!*args) {
  339.         if ((where = get_world_header()) == NULL) 
  340.             oputs("% No default world is set.");
  341.     } else if ((port = strchr(args, ' ')) == NULL) {
  342.         if ((where = find_world(args)) == NULL)
  343.             do_hook(H_CONFAIL, "%% Connection to %s failed: %s", "%s %s",
  344.                 args, "world unknown");
  345.     } else if (strchr(port + 1, ' ')) {
  346.         oputs("% Too many arguments.");
  347.     } else {
  348.         *port++ = '\0';
  349.         sprintf(name, "(unnamed%d)", unnamed++);
  350.         where = new_world(name, "", "", args, port, "");
  351.         where->flags |= WORLD_TEMP;
  352.     }
  353.  
  354.     if (where) connect_to(where, autologin);
  355. }
  356.  
  357. static void handle_addworld_command(args)
  358.     char *args;
  359. {
  360.     if (*args) addworld(args);
  361. }
  362.  
  363. static void handle_unworld_command(args)
  364.     char *args;
  365. {
  366.     if (*args) remove_world(args);
  367. }
  368.  
  369. static void handle_purgeworld_command(args)
  370.     char *args;
  371. {
  372.     if (*args) purge_world(args);
  373. }
  374.  
  375. static void handle_saveworld_command(args)
  376.     char *args;
  377. {
  378.     write_worlds(args);
  379. }
  380.  
  381. static void handle_dc_command(args)
  382.     char *args;
  383. {
  384.     disconnect(args);
  385. }
  386.  
  387. /*************
  388.  * Processes *
  389.  *************/
  390.  
  391. static void handle_quote_command(args)  /* quote file/command/history */
  392.     char *args;
  393. {
  394.     if (*args) start_quote(args);
  395. }
  396.  
  397. static void handle_repeat_command(args) /* repeat action n times */
  398.     char *args;
  399. {
  400.     if (*args) start_repeat(args);
  401. }
  402.  
  403. static void handle_kill_command(args)
  404.     char *args;
  405. {
  406.      if (*args) do_kill(atoi(args));
  407. }
  408.  
  409. static void handle_ps_command(args)
  410.     char *args;
  411. {
  412.     if (*args) oputs("% Arguments disregarded.");
  413.     do_ps();
  414. }
  415.  
  416. /********
  417.  * Misc *
  418.  ********/
  419.  
  420.  
  421. static void handle_quit_command(args)
  422.     char *args;
  423. {
  424.     set_done();
  425. }
  426.  
  427. static void handle_recall_command(args)
  428.     char *args;
  429. {
  430.     recall_history(args, NULL);
  431. }
  432.  
  433. static void handle_sh_command(args)
  434.     char *args;
  435. {
  436.     char *shell;
  437.     extern int shpause;
  438.  
  439.     if (*args) {
  440.         shell = args;
  441.         do_hook(H_SHELL, "%% Executing %s: \"%s\"", "%s %s", "command", shell);
  442.     } else {
  443.         if ((shell = getenv("SHELL")) == NULL) shell = "/bin/sh";
  444.         do_hook(H_SHELL, "%% Executing %s: %s", "%s %s", "shell", shell);
  445.     }
  446.     if (visual) fix_screen();
  447.     cooked_echo_mode();
  448.     system(shell);
  449.     if (shpause) {
  450.         oputs("% Done-- press a key to return.");
  451.         getch();
  452.     }
  453.     cbreak_noecho_mode();
  454.     setup_screen();
  455. #ifdef MAILDELAY
  456.     check_mail();
  457. #endif
  458.     do_hook(H_RESUME, "%% Resuming TinyFugue", "");
  459. }
  460.  
  461. static void handle_version_command(args)
  462.     char *args;
  463. {
  464.     extern char version[];
  465.     oprintf("%% %s.", version);
  466. }
  467.  
  468. static void handle_lcd_command(args)
  469.     char *args;
  470. {
  471. #ifndef SYSVTTY
  472. # ifndef hpux
  473.     smallstr buffer;
  474. # endif
  475. #endif
  476.     STATIC_BUFFER(dirname)
  477.  
  478.     Stringcpy(dirname, args);
  479.     Stringexpand(dirname);
  480.     if(dirname->len && chdir(dirname->s) == -1)
  481.         oprintf("%% Can't change to %S", dirname);
  482.  
  483. #ifndef SYSVTTY
  484. # ifndef hpux
  485.     oprintf("%% Current directory is %s", getwd(buffer));
  486. # endif
  487. #endif
  488. }
  489.  
  490. static void handle_send_command(args)
  491.     char *args;
  492. {
  493.     if (*args) do_send(args);
  494. }
  495.  
  496. static void handle_echo_command(args)
  497.     char *args;
  498. {
  499.     char c;
  500.     short attrs = 0, wflag = 0, nflag = 0;
  501.     World *world = NULL;
  502.  
  503.     startopt(args, "a:w:");
  504.     while (c = nextopt(&args, NULL)) {
  505.         switch (c) {
  506.         case 'a': case 'f':
  507.             if ((attrs |= parse_attrs(args)) < 0) return;
  508.             break;
  509.         case 'w':
  510.             wflag = 1;
  511.             if (!*args) world = xworld();
  512.             else if ((world = find_world(args)) == NULL) {
  513.                 oprintf("%% World %s not found.", args);
  514.                 return;
  515.             }
  516.             break;
  517.         default:
  518.             return;
  519.         }
  520.     }
  521.     if (!wflag) output(args, nflag ? attrs : (attrs | F_NEWLINE));
  522.     else if (world) world_output(world, args, attrs);
  523.     else oputs("% No current world.");
  524. }
  525.  
  526. static void handle_input_command(args)
  527.     char *args;
  528. {
  529.     handle_input_string(args, strlen(args));
  530. }
  531.  
  532. static void handle_grab_command(args)
  533.     char *args;
  534. {
  535.     extern int keyboard_pos;
  536.     extern Stringp keybuf;
  537.  
  538.     Stringcpy(keybuf, args);
  539.     keyboard_pos = keybuf->len;
  540.     if (visual && is_refresh_pending()) do_line_refresh();
  541.     do_replace();
  542. }
  543.