/*
* do_commands.c -- doing the different PMF commands
*
* PMF -- Padrone's MudFrontend, a frontend for (maybe mostly LP-)mud
* Thomas Padron-McCarthy (Email: padrone@lysator.liu.se), 1990, 1991
* Share and enjoy, but be nice: don't steal my program! Hugo is watching!
* This file latest updated: Sept 23, 1993
*
*/
#include <strings.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include "safe_malloc.h"
#include "config.h"
#include "pmf.h"
#include "globals.h"
extern char *get_input_line(), *expand_alias(),
*find_alias_string(),
*expand_history(), *get_statstring(), *getmud(),
*expand_variables(),
*find_robot_action_string();
#ifdef SOUND
char *find_sound_action_string();
#endif
extern char version[];
extern char *getenv();
extern char *get_now_date_string();
/*---------------------------------------------------------------------------*/
cmd_connect(host, port)
char *host, *port;
{
if (connected)
error("You cannot connect when already connected.");
/* If arguments were given to the "connect" command, use those.
* Else, if a host/or and port were given as arguments to pmf, use those.
* Else, if the variables "host" and/or "port" are set, use those.
* Otherwise, use the defaults from config.h.
*/
if (host)
set_variable("host", host);
else if (arg_host_string)
set_variable("host", arg_host_string);
else if (!host_string)
set_variable("host", DEFAULT_HOST_STRING);
if (port)
set_variable("port", port);
else if (arg_port_string)
set_variable("port", arg_port_string);
else if (!port_string) {
char *ps = safe_malloc(10);
sprintf(ps, "%d", DEFAULT_PORT_NUMBER);
set_variable("port", ps);
}
host = host_string; /* The value of the variable "host" */
port = port_string; /* The value of the variable "port" */
ldisplay("Connecting to host %s port number %s...", host, port);
fflush(stdout);
connect_to_mud(host, port);
ldisplay(" Connected.\n");
} /* cmd_connect */
cmd_disconnect()
{
if (!connected)
error("You cannot disconnect if you are not connected.");
disconnect();
ldisplay("PMF: Disconnected from host %s port number %s.\n", host_string, port_string);
fflush(stdout);
} /* cmd_disconnect */
cmd_perform(cmd, confirm_string)
char *cmd, *confirm_string;
{
ASSERT(cmd);
if (!confirm_string)
confirm_string = "";
queue_mudline(cmd, confirm_string);
} /* cmd_perform */
int is_comment_line(cp)
register char *cp;
{
/* First, skip leading white space. */
while (cp && *cp && isspace(*cp)) /* ARONSSON WAS HERE */
++cp;
if (!cp || !*cp) /* ARONSSON WAS HERE */
return 1; /* Empty lines are comment lines */
/* Comment lines are lines that start with # (even after white space) */
return (*cp == '#');
} /* is_comment_line */
cmd_source(arg)
char *arg;
{
FILE *fp, *old_source_file;
char *filename, *this_line, *old_source_file_name;
int old_sourcing;
ASSERT(arg);
if (sourcing >= MAX_SOURCING_LEVELS)
error("Source command loop. Too many levels (%d) nested.", sourcing + 1);
if ((fp = fopen(arg, "r")) == NULL) {
uerror("Couldn't open the file \"%s\".", arg);
}
else {
filename = strcpy(safe_malloc(strlen(arg) + 1), arg);
/* Remember the file and its name so we can close it if an error occurs.
* Save the old ones first, so we can restore them after this command.
* We will also save the old "sourcing" state,
* to permit nested source commands.
*/
old_source_file = the_source_file;
old_source_file_name = the_source_file_name;
the_source_file = fp;
the_source_file_name = filename;
old_sourcing = sourcing;
sourcing += 1;
if (verbose)
ldisplay("\nReading commands from \"%s\" (%s).\n",
filename, get_statstring(filename));
this_line = get_input_line(fp);
while (! feof(fp)) {
if (!is_comment_line(this_line))
handle_command(this_line, 0);
if (verbose)
ldisplay(".");
this_line = get_input_line(fp);
} /* while */
if (verbose) {
ldisplay("\n");
ldisplay("Done \"%s\".\n", filename);
}
/* Close the file, free the file name buffer, and restore all states. */
fclose(fp);
safe_free(filename);
the_source_file = old_source_file;
the_source_file_name = old_source_file_name;
sourcing = old_sourcing;
}
} /* cmd_source */
cmd_send(arg, confirm_string, shutup)
char *arg, *confirm_string;
int shutup;
{
FILE *fp;
char *filename;
static char this_line[MAX_LINE_LENGTH + 1];
int line_length;
ASSERT(arg);
if (!confirm_string)
confirm_string = "";
if (sending || receiving || getfiling) {
message("Cannot do more than one send or receive command at the same time.");
}
else if ((fp = fopen(arg, "r")) == NULL) {
uerror("Couldn't open the file \"%s\".", arg);
}
else {
filename = strcpy(safe_malloc(strlen(arg) + 1), arg);
/* Remember the file and its name so we can close it if an error occurs.
* We don't need to save the old ones first, nor the old value of
* "sending", since send and restore commands cannot nest.
*/
the_open_file = fp;
the_open_file_name = filename;
sending = 1;
if (!shutup)
ldisplay("Sending file \"%s\" (%s).\n",
filename, get_statstring(filename));
while (fgets(this_line, MAX_LINE_LENGTH + 1, fp) && !feof(fp)) {
USER_DEBUG(("going to send: %s", this_line));
line_length = strlen(this_line);
if (this_line[line_length - 1] == '\n')
this_line[line_length - 1] = '\0';
else if (this_line[line_length - 1])
message("Long line (%d characters) split when sending %s.",
MAX_LINE_LENGTH + 1 , filename);
queue_mudline(this_line, confirm_string);
ldisplay(".");
while (!ok_to_send()) {
communicate_with_mud();
/* handle_the_player(); */
}
} /* while */
fclose(fp);
if (!shutup) {
ldisplay("\n");
ldisplay("Finished sending \"%s\".\n", filename);
}
/* Close the file, free the file name buffer, and restore all states. */
fclose(fp);
safe_free(filename);
the_open_file = NULL;
the_open_file_name = NULL;
sending = 0;
}
} /* cmd_send */
static saved_shutup;
cmd_receive(filename_parameter, stop_string, shutup)
char *filename_parameter, *stop_string;
int shutup;
{
char *filename;
int stop_string_length;
ASSERT(filename_parameter);
ASSERT(stop_string);
if (sending || receiving || getfiling) {
message("Cannot do more than one send or receive command at the same time.");
}
else if (backup_file(filename_parameter) == -1)
uerror("Couldn't backup.");
else if ((the_open_file = fopen(filename_parameter, "w")) == NULL) {
uerror("Couldn't open the file \"%s\".", filename_parameter);
}
else {
filename = strcpy(safe_malloc(strlen(filename_parameter) + 1),
filename_parameter);
stop_string_length = strlen(stop_string);
receive_stop_string = strcpy(safe_malloc(stop_string_length + 1),
stop_string);
/* Remember the file and its name so we can close it if an error occurs: */
/* We already set "the_open_file". */
the_open_file_name = filename;
receiving = 1;
if (verbose && !shutup)
ldisplay("\n");
if (!shutup)
ldisplay("Receiving into file \"%s\".\n", filename);
saved_shutup = shutup;
}
} /* cmd_receive */
stop_receiving()
{
/* Close the file, free the file name buffer, and restore all states. */
fclose(the_open_file);
if (!saved_shutup)
ldisplay("Done. Received \"%s\" (%s).\n", the_open_file_name,
get_statstring(the_open_file_name));
safe_free(the_open_file_name);
the_open_file = NULL;
the_open_file_name = NULL;
receiving = 0;
} /* stop_receiving */
cmd_last(arg)
char *arg;
{
int nr_lines;
if (arg)
nr_lines = atoi(arg);
else
nr_lines = 0;
show_last(nr_lines);
} /* cmd_last */
cmd_dump(arg)
char *arg;
{
FILE *fp;
ASSERT(arg);
if (backup_file(arg) == -1)
uerror("Couldn't backup.");
else if ((fp = fopen(arg, "w")) == NULL) {
uerror("Couldn't open the file \"%s\".", arg);
}
else {
dump_variables(fp);
dump_alias(fp);
dump_robot_actions(fp);
#ifdef SOUND
dump_sound_actions(fp);
#endif
dump_gags(fp);
fclose(fp);
#ifdef SOUND
ldisplay("Alias definitions, robot actions, sounds, gags and variables dumped\n");
#else
ldisplay("Alias definitions, robot actions, gags and variables dumped\n");
#endif
ldisplay("to the file \"%s\" (%s).\n", arg, get_statstring(arg));
}
} /* cmd_dump */
cmd_gag(pattern)
char *pattern;
{
if (!pattern)
list_gags(stdout);
else
add_gag(pattern);
} /* cmd_gag */
cmd_ungag(name)
char *name;
{
remove_gag(name);
} /* cmd_ungag */
cmd_system(cmd)
char *cmd;
{
int retval;
if (!cmd)
cmd = getenv("SHELL");
if (!cmd)
cmd = "/bin/sh";
retval = system(cmd);
if (retval != 0)
message("system(\"%s\") returned %d.", cmd, retval);
} /* cmd_system */
cmd_log(arg, isdebug)
char *arg;
int isdebug;
{
struct stat dummy_statbuf;
if (log_file && arg)
message("A log file is already open. You cannot open another!");
else if (!log_file && !arg)
message("But on what file should I write the log?");
else if (log_file) {
fprintf(log_file, "\n----------\n");
fprintf(log_file, "%24.24s: Finished writing MUD dialogue.\n",
get_now_date_string());
ldisplay("Closing log file \"%s\".\n", log_file_name);
fclose(log_file);
safe_free(log_file_name);
log_file = NULL;
}
else {
if (stat(arg, &dummy_statbuf) == 0)
ldisplay("The file \"%s\" exists. I will appended the log at its end.\n",
arg);
if ((log_file = fopen(arg, "a")) == NULL)
uerror("Couldn't open log file \"%s\".", arg);
else {
char *user_name;
log_file_name = strcpy(safe_malloc(strlen(arg) + 1), arg);
debug_log = isdebug;
ldisplay("Saving MUD dialogue %s on the file \"%s\".\n",
isdebug ? " and debug info " : "", log_file_name);
fprintf(log_file, "This log file, \"%s\",\n", log_file_name);
user_name = getenv("USER");
fprintf(log_file, "was written by PMF version %s,\n", version);
fprintf(log_file, "and it was opened %24.24s by user %s\n",
get_now_date_string(),
user_name ? user_name : "(unknown)");
fprintf(log_file, "when connected to %s %s.\n",
host_string, port_string);
fprintf(log_file, "----------\n\n");
}
}
} /* cmd_log */
cmd_set(var, value)
char *var, *value;
{
if (!var)
list_variables(stdout);
else if (!value)
set_variable(var, "true");
else if ( !strcmp(value, "false")
|| !strcmp(value, "FALSE")
|| !strcmp(value, "nil"))
message("Not done. You probably want to use \"frontunset %s\" instead.", var);
else
set_variable(var, value);
} /* cmd_set */
cmd_unset(var)
char *var;
{
unset_variable(var);
} /* cmd_unset */
cmd_status()
{
ldisplay("\n");
ldisplay(" This is PMF (Padrone's MudFrontend) version %s.\n", version);
ldisplay(" Achtung: %s.", achtung ? "ON" : "OFF");
ldisplay(" Robot: %s.", robot_mode ? "ON" : "OFF");
#ifdef SOUND
ldisplay(" Sound: %s.", sound_mode ? "ON" : "OFF");
#endif
ldisplay(" Verbose: %s.", verbose ? "ON" : "OFF");
ldisplay(" Ignore EOF: %s.\n", ignoreeof ? "ON" : "OFF");
ldisplay(" Slash-commands: %s.", slash_commands ? "ON" : "OFF");
ldisplay(" Replace control chars: %s.", replace_control ? "ON" : "OFF");
ldisplay(" Show receive-lines: %s.\n", show_receive ? "ON" : "OFF");
ldisplay(" Debug: %s.", debug ? "ON" : "OFF");
ldisplay(" Prompt: ");
if (pmf_prompt)
ldisplay("\"%s\".\n", pmf_prompt);
else
ldisplay("NONE.\n");
ldisplay(" Max history length: %d.", query_max_history());
ldisplay(" Max last list length: %d.", lines_to_save);
ldisplay(" Screen length: %d.\n", screen_length);
ldisplay(" You have defined %d aliases, %d robot actions",
query_nr_aliases(), query_nr_robot_actions());
#ifdef SOUND
ldisplay(", %d sounds", query_nr_sound_actions());
#endif
ldisplay(" and %d gags.\n", query_nr_gags());
if (log_file)
ldisplay(" Logging: ON. File is \"%s\".\n", log_file_name);
else
ldisplay(" Logging: OFF.\n");
ldisplay(" Sourcing levels nested: %d.", sourcing);
if (sourcing)
ldisplay(" File is \"%s\".\n", the_source_file_name);
else
ldisplay("\n");
ldisplay(" Sending: %s.", sending ? "ON" : "OFF");
ldisplay(" Receiving: %s.", receiving ? "ON" : "OFF");
ldisplay(" Getfile: %s.", getfiling ? "ON" : "OFF");
if (sending || receiving || getfiling)
ldisplay(" File is \"%s\".\n", the_open_file_name);
else
ldisplay("\n");
ldisplay(" The queue of lines to send to MUD is %d lines long.",
query_queue_to_mud_size());
if (query_waiting_for_response())
ldisplay(" Waiting for response.\n");
else
ldisplay("\n");
if (internal_debug)
ldisplay(" *** Internal DEBUG *** is on!\n");
if (ipc_debug)
ldisplay(" *** IPC DEBUG *** is on!\n");
ldisplay("\n");
} /* cmd_status */
cmd_alias(arg1, rest)
char *arg1, *rest;
{
char *the_expanded;
if (!arg1)
list_alias(stdout);
else if (!rest) {
the_expanded = find_alias_string(arg1);
if (the_expanded)
ldisplay("%s\t%s\n", arg1, the_expanded);
else if (verbose)
message("Not defined.");
}
else if (!strcmp(arg1, "quote"))
message("It would be pointless to redefine \"quote\", so I won't let you.");
else
add_alias(arg1, rest);
} /* cmd_alias */
cmd_unalias(arg)
char *arg;
{
remove_alias(arg);
} /* cmd_unalias */
cmd_action(arg1, rest)
char *arg1, *rest;
{
char *the_action;
if (!arg1)
list_robot_actions(stdout);
else if (!rest) {
the_action = find_robot_action_string(arg1);
if (the_action)
ldisplay("%s\t%s\n", arg1, the_action);
else if (verbose)
message("Not defined.");
}
else
add_robot_action(arg1, rest);
} /* cmd_action */
cmd_unaction(arg)
char *arg;
{
remove_robot_action(arg);
} /* cmd_unaction */
cmd_unactionall()
{
remove_all_robot_actions();
} /* cmd_unactionall */
#ifdef SOUND
cmd_sound(arg1, rest)
char *arg1, *rest;
{
char *the_action;
if (!arg1)
list_sound_actions(stdout);
else if (!rest) {
the_action = find_sound_action_string(arg1);
if (the_action)
ldisplay("%s\t%s\n", arg1, the_action);
else if (verbose)
message("Not defined.");
}
else
add_sound_action(arg1, rest);
} /* cmd_sound */
cmd_unsound(arg)
char *arg;
{
remove_sound_action(arg);
} /* cmd_unsound */
#endif SOUND
cmd_beep()
{
ldisplay("\007");
} /* cmd_beep */
cmd_echo(str)
char *str;
{
if (str)
ldisplay("%s\n", str);
else
ldisplay("\n");
} /* cmd_echo */
cmd_cd(str)
char *str;
{
if (str == NULL)
str = getenv("HOME");
if (str == NULL)
error("Cannot find your home directory: $HOME not set.");
if (chdir(str) == -1)
uerror("chdir to %s failed.", str);
} /* cmd_cd */
cmd_history(arg)
char *arg;
{
int nr_lines;
if (arg)
nr_lines = atoi(arg);
else
nr_lines = 0;
print_history(stdout, nr_lines);
} /* cmd_history */
cmd_quit()
{
say_goodbye_and_exit(0);
} /* cmd_quit */
syntax highlighted by Code2HTML, v. 0.9.1