tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/*
// tsh.c: TMI-shell or Tru-shell -- written by Truilkan@TMI 92/02/05 
//        meant to be inherited by player.c
//
// Brutally hacked up and destroyed by Buddha to install something "better"
// on 3-7-92
//
// 1992/03/08 - hacked again by Truilkan@TMI to fix pushd and popd
//
// 1993/02/06 - Multiple command repeat capability by Watcher@TMI
//
// 1993/02/22 - Allowing silent queries to write_prompt() by Watcher@TMI
//
// 1993/03/30 -	Uses STACK not CSTACK (makes `dirs' cmd easier)
//		Uses tilde_path in prompt.
//		Cleaned up a bit. (Zak@tmi-2)
// 1993/08/05 Grendel@tmi-2 - Added test for files in ~/tsh/
// 94-11-09   - Leto added an int typecast
*/

#include <adt_defs.h>
#include <commands.h>
#include <tsh.h>
#include <uid.h>

#define DEFAULT_PROMPT "> "
#define MAX_HIST_SIZE  50
#define MIN_HIST_SIZE  20
#define MIN_PUSHD_SIZE 5
#define MAX_PUSHD_SIZE 50

/*
    STACK_ADT should be inherited from here so that this object can have
    its own private stack
*/
private inherit STACK_ADT;       /* for pushd and popd */

private static string tsh_prompt;
private static int cur, hist_size, pushd_size, custom_prompt;

string do_nicknames(string arg);
string do_alias(string arg);
string do_substitution(string arg) ;
string handle_history(string arg);
nomask mixed query( string label );

/* do_new: called by the "new" command */

int do_new()
{
    string d1, d2;

    tsh_prompt = (string)this_object()->getenv("prompt");
    tsh_prompt = !tsh_prompt ? DEFAULT_PROMPT : tsh_prompt + " ";
    custom_prompt = (tsh_prompt != DEFAULT_PROMPT);

    d1 = (string)this_object()->getenv("pushd");
    pushd_size = 0;
    if (d1)
	sscanf(d1,"%d",pushd_size);
    if (pushd_size > MAX_PUSHD_SIZE)
	pushd_size = MAX_PUSHD_SIZE;
    if (!pushd_size)
	pushd_size = MIN_PUSHD_SIZE;

    d1 = (string)this_object()->getenv("history");
    hist_size = 0;
    if (stringp(d1))
	sscanf(d1,"%d",hist_size);
    else if (intp(d1))
        hist_size = (int)d1; // Leto 
    if (hist_size > MAX_HIST_SIZE)
	hist_size = MAX_HIST_SIZE;
    if (!intp(hist_size) || hist_size <= 0)
	hist_size = MIN_HIST_SIZE;
    return 1;
} // do_new


/* push current directory onto the stack and cd to dir named "arg" */
int pushd(string arg)
{
    string path;

    if (!arg && (string)this_object()->getenv("pushdtohome"))
	arg = "~";
    path = (string)this_object()->query("cwd");
    if (((int)CMD_CD->cmd_cd(arg)))
    {
	if (push(path) == -1)
	    write("dirstack full - try popd-ing some elements first\n");
    }
    return 1;
} // pushd


int popd()
{
    mixed dir;

    dir = pop();
    if ((int)dir == -1)
	write("Directory stack is empty.\n");
    else
	CMD_CD->cmd_cd((string)dir);
    return 1;
} // popd


mixed *dirs()
{
    return query_stack();
}


void initialize_tsh()
{
    string rcfile;

    do_new();
    if (pushd_size)
	alloc(pushd_size);
// According to Beek, the next 2 lines shoulf go, but that
// kills history completely..... Leto 942711
    if (hist_size)
	history::hist_alloc(hist_size);
    rcfile = user_path((string)this_object()->query("name")) + ".login";
    if( file_size(rcfile) > 0 )
	this_object()->tsh(rcfile);
} // initialize_tsh


string write_prompt(int silent)
{
    string path, prompt, tmp;

    if (custom_prompt)
    {
	prompt = tsh_prompt;
	prompt = replace_string(prompt,"$D",
			tilde_path((string)this_object()->query("cwd"), 0));
	prompt = replace_string(prompt,"\\n","\n");
	prompt = replace_string(prompt,"$N",lower_case(mud_name()));
	prompt = replace_string(prompt,"$T",ctime(time())) ;
	prompt = replace_string(prompt,"$C",""+(query_cmd_num() + 1));
    }
    else
	prompt = DEFAULT_PROMPT;
    if(!silent)
        message("prompt", prompt, this_player());
    return prompt;
} // write_prompt


static nomask string process_input(string arg)
{
    int loop, num, macro;

    if (arg && arg != "")
    {
	if(sscanf(arg, "%d %s", num, arg) == 2)
	    macro = 1;

	arg = do_substitution(arg) ;
	arg = do_nicknames(arg);
	arg = do_alias(arg);
	arg = handle_history(arg);

    //	Allow multiple repeat actions like '5 north' as well as
    //	alias commands.   - Watcher  (02/05/93)

	if(macro && num && arg && arg != "" && !previous_object())
	{
		if(num > 10) {
		write("Command macro increment too high.\n");
		return ""; }
 
	    for(loop=0; this_player() && loop < num; loop++)
		if(!command(arg))
		{
		    write("Could not complete action. Command macro halted.\n");
		    break;
		}
	    return "";
	}
    }
   if( strlen( arg ) > 5 && arg[0..5] == "passwd" ) {
      CMD_PASSWD -> cmd_passwd( (strlen( arg ) > 6 ? arg[7..<1] : 0) );
      return "";
   }
    return arg;
} // process_input


nomask int tsh(string file)
{
    string contents, euid, *lines;
    int j, len;

    euid = geteuid( previous_object() );
	// 93-02-12 pallando (_tsh wasn't working)
    if (  ( euid != geteuid( this_object() ) )
       && ( euid != ROOT_UID )
       && !adminp(euid) )
	return 0;
    if (!file)
    {
	notify_fail("usage: tsh filename\n");
	return 0;
    }
    contents = read_file( resolv_path( "cwd", file ) );
    if (!contents) {
	contents = read_file( resolv_path( "cwd", "~/tsh/"+file ) );
	if (!contents)
	{
	    notify_fail("tsh: couldn't read " + file + "\n");
	    return 0;
	}
    }
    lines = explode(contents,"\n");
    len = sizeof(lines);
    for (j = 0; this_player() && j < len; j++)
    {
	if (lines[j][0] != '#' && !command(lines[j]))
	{
	    write(file + ": terminated abnormally on line #" + (j+1) + "\n");
	    write("while doing: " + lines[j] + "\n");
	    break;
	}
    }
    return 1;
} // tsh

// This function allows for ^foo^bar substitutions.

nomask string do_substitution (string arg) {

	string pre,post,old,New,lastcom ;

        if (arg == "^^") {
		write ((lastcom = query_last_command()) + "\n");
		return lastcom;
	}

	if (sscanf(arg,"^%s^%s",old,New)!=2) {
		return arg ;
	}

	lastcom = query_last_command() ;
	if (!lastcom || lastcom=="") {
		write ("No previous command.\n") ;
		return "" ;
	}

        if (old == "") {
		// allow you to prepend last string
		write (New + lastcom + "\n");
		return New + lastcom ;
	}

	if (sscanf(lastcom, "%s" + old + "%s", pre,post) != 2) {
		write ("Failed substitution.\n") ;
		return "" ;
	}
	write (pre+New+post+"\n") ;
	return pre+New+post ;
}