/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/*
 * Mar 11, 1994 - Bannor, added indent()
 * Nivek, 13-Apr-94, added wiz_present to 'cd'.
 *    added 'qexe*c', which doesn't print return values or errors, and
 *    fixed execute() so that it reports the error it so carefully records.
 */
#pragma save_binary
inherit "/std/basic/ls";
inherit "/std/basic/ls_new";
inherit "/global/le";
inherit "/global/wiz_object_comm";
inherit "/global/player";
inherit "/global/wiz_inter_comm";
inherit "/global/wiz_info_comm";

#define MASTER "/secure/master"
#define COL "%^CYAN%^"
#define CHECKOUT "/obj/handlers/checkout"
#define SECURITY if(this_player(1) != this_player()) return 0;

static string in_editor;

varargs object *wiz_present( string str, object onobj, int nogoout );
string  desc_object( mixed o );
string  desc_f_object( object o );

static void wiz_commands()
{
    add_action( "makedir", "mk*dir" );
    add_action( "removedir", "rmd*ir" );
    add_action( "update", "upd*ate" );
    add_action( "discard", "di*scard" );
    add_action( "rm_file", "rm" );
    add_action( "indent_file", "indent" );
    add_action( "cp_file", "cp" );
    add_action( "mv_file", "mv" );
    add_action( "load", "lo*ad" );
    add_action( "clone", "cl*one" );
    if( "/obj/handlers/cregrade"->query_cre_grade( query_name() ) > 19 )
    {
	add_action( "execute", "exe*c" );
	add_action( "execute", "qexe*c" );
    }
    add_action( "do_checkout", "checkout" );
    add_action( "do_return", "checkin" );
    add_action( "do_owner", "owner" );
    add_action( "do_filesout", "files" );
    add_action( "backup_file", "backup" );
    wiz_object_comm::wiz_commands();
    wiz_inter_comm::wiz_commands();
    wiz_info_comm::wiz_commands();
}

/* These commands should go to players of level >=20,
   and creators logged on as players, but never do,
   as they are only inherited by the creator body,
   and not the player one. */

static void app_commands()
{
    add_action( "du", "du" );
    add_action( "grep", "gr*ep" );
    add_action( "reg_ex_grep", "rg*rep" );
    wiz_object_comm::app_commands();
    wiz_info_comm::app_commands();
}

all_commands()
{
    add_action( "tail_file", "ta*il" );
    add_action( "what_dir", "pw*d" );
    add_action( "list_files", "nls" );
    add_action( "new_list_files", "ls" );
    add_action( "change_dir", "cd" );
    add_action( "exa_file", "cat" );
    add_action( "do_more", "mo*re" );
    add_action( "edit", "ed" );
    add_action( "le", "le" );
    add_action( "set_home_dir", "homed*ir" );
    add_action( "do_sar", "sar" );
    wiz_object_comm::all_commands();
    wiz_info_comm::all_commands();
}

static int mv_file( string str )
{
    string *filenames, dest, *fnames, source;
    int     loop, fs;

    SECURITY

	if( !str )
    {
	notify_fail( "Usage : mv file [file|dir...]\n" );
	return 0;
    }
    fnames = explode( str, " " );
    filenames = get_files( implode( fnames[ 0..sizeof( fnames ) - 2 ], " " ) );
    if( !sizeof( filenames ) )
    {
	notify_fail( "Cannot find file(s).\n" );
	return 0;
    }
    dest = fnames[ sizeof( fnames ) - 1 ];
    dest = get_path( dest );
    if( !dest )
    {
	write( "No destination\n" );
	return 1;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	if( file_size( str ) == -1 )
	{
	    write( "No such file : " + str + "\n" );
	    continue;
	}
	fs = file_size( dest );
	if( fs == -2 )
	{
	    string *names;

	    names = explode( str, "/" );
	    fs = file_size( dest + "/" + names[ sizeof( names ) - 1 ] );
	    if( fs != -1 )
	    {
		write( "file exists " + dest + "/" + names[ sizeof( names ) - 1 ] + "\n" );
		continue;
	    }
	    rename( str, dest + "/" + names[ sizeof( names ) - 1 ] );
	}
	else
	{
	    if( fs != -1 )
	    {
		write( "File exists : " + dest + "\n" );
		continue;
	    }
	    rename( str, dest );
	}
    }
    if( sizeof( filenames ) > 1 )
	write( COL + "Files moved sucessfully.%^RESET%^\n" );
    else
	write( COL + "File moved sucessfully.%^RESET%^\n" );
    return 1;
}


static int cp_file( string str )
{
    string *filenames, text, dest, *fnames;
    int     loop, fs;

    SECURITY

	if( !str )
    {
	notify_fail( "Usage : cp file [file|dir...]\n" );
	return 0;
    }
    fnames = explode( str, " " );
    filenames = get_files( implode( fnames[ 0..sizeof( fnames ) - 2 ], "/" ) );
    if( !sizeof( filenames ) )
    {
	notify_fail( "Cannot find file(s)\n" );
	return 0;
    }
    dest = fnames[ sizeof( fnames ) - 1 ];
    dest = get_path( dest );
    if( !dest )
    {
	write( "No destination\n" );
	return 1;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	text = read_file( str );
	if( !text )
	{
	    write( "No such file : " + str + "\n" );
	    continue;
	}
	fs = file_size( dest );
	if( fs == -2 )
	{
	    string *names;

	    names = explode( str, "/" );
	    fs = file_size( dest + "/" + names[ sizeof( names ) - 1 ] );
	    if( fs != -1 )
	    {
		write( "file exists " + dest + "/" +
		       names[ sizeof( names ) - 1 ] + "\n" );
		continue;
	    }
	    write_file( dest + "/" + names[ sizeof( names ) - 1 ], text );
	}
	else
	{
	    if( fs != -1 )
	    {
		write( "File exists : " + dest + "\n" );
		continue;
	    }
	    write_file( dest, text );
	}
    }
    if( sizeof( filenames ) > 1 )
	write( COL + "Files copied sucessfully.%^RESET%^\n" );
    else
	write( COL + "File copied sucessfully.%^RESET%^\n" );
    return 1;
}

static int do_update( object *ov )
{
    string  pname, dummy, err;
    int     i, j;
    object *invent, rsv, env, dup, loaded;

    SECURITY

	"room/void"->bingle_bingle();

    rsv = find_object( "room/void" );
    if( !rsv )
    {
	notify_fail( "The void is lost!\n" );
	return 0;
    }

    for( i = 0; i < sizeof( ov ); i++ )
    {
	if( !ov[ i ] )
	    continue;
	env = environment( ov[ i ] );
	invent = all_inventory( ov[ i ] );

	for( j = 0; j < sizeof( invent ); j++ )
	    invent[ j ]->move( rsv );

	pname = file_name( ov[ i ] );
	if( sscanf( pname, "%s#%d", pname, dummy ) != 2 )
	{			/* a room ? */
	    ov[ i ]->dest_me();
	    if( ov[ i ] )
		ov[ i ]->dwep();
	    if( ov[ i ] )
		destruct( ov[ i ] );
	    file_size( "/secure/master" );
	    if( !ov[ i ] )
		ov[ i ] = find_object( pname );
	    call_other( pname, "??" );
	    ov[ i ] = find_object( pname );
	}
	else
	{
	    loaded = find_object( pname );
	    if( loaded )
		loaded->dest_me();
	    if( loaded )
		loaded->dwep();
	    if( loaded )
		destruct( loaded );

	    dup = clone_object( pname );
	    if( dup && ov[ i ] )
	    {
		ov[ i ]->dest_me();
		if( ov[ i ] )
		    ov[ i ]->dwep();
		if( ov[ i ] )
		    destruct( ov[ i ] );
		ov[ i ] = dup;
	    }
	}

	if( !ov[ i ] )
	{
	    write( "I seem to have lost your object.\n" );
	    return 1;
	}

	for( j = 0; j < sizeof( invent ); j++ )
	    if( invent[ j ] )
		invent[ j ]->move( ov[ i ] );

	if( env )
	    ov[ i ]->move( env );
	write( COL + "Updated " + desc_f_object( ov[ i ] ) + ".%^RESET%^\n" );
    }
    return 1;
}


int     update( string str )
{
    string  tring, *filenames, err;
    object  ob, *val, *obs;
    int     loop, loop2;

    SECURITY

	notify_fail( "No such object.\n" );
    tring = str;
    if( !str || str == "here" )
    {
	str = file_name( environment() );
	sscanf( str, "%s#%d", str, loop );
	filenames = ({ "/" + str });
	str = "here";
    }
    else
	filenames = get_cfiles( str );
    if( sizeof( filenames ) == 0 )
    {
	val = wiz_present( tring, this_player() );
	if( !sizeof( val ) )
	{
	    notify_fail( "No matching objects/filenames\n" );
	    return 0;
	}
	return do_update( val );
    }
    obs = ({ });
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	ob = find_object( str );
	if( !ob )
	{
	    if( file_size( str ) >= 0 )
	    {
		if( !(err = catch( str->bing_with_me() )) )
		    write( COL + "Loaded " + str + "%^RESET%^\n" );
		else
		    write( COL + "Failed to load " + str +
			   ", error: " + err + "%^RESET%^\n" );
	    }
	    else
	    {
		val = wiz_present( tring, this_player() );
		obs += val;
	    }
	}
	else
	    obs += ({ ob });
    }
    if( !obs )
	return 0;
    else
	return do_update( obs );
}				/* update() */


/* This is for querying about objects who don't want to be destructed */
static object discard_obj;

int     discard( string str )
{
    string *file_names;
    int     loop;
    string  err;

    if( !str )
    {
	notify_fail( "Discard what?\n" );
	return 0;
    }
    file_names = get_cfiles( str );
    if( !sizeof( file_names ) )
    {
	notify_fail( "No match found with " + str + ".\n" );
	return 0;
    }
    for( loop = 0; loop < sizeof( file_names ); loop++ )
    {
	str = file_names[ loop ];
	discard_obj = find_object( str );
	if( !discard_obj )
	{
	    if( file_size( str ) < 0 )
		notify_fail( "No such file " + str + "\n" );
	    else
		write( str + " is not loaded.\n" );
	    continue;
	}
	err = catch( discard_obj->dest_me() );
	handle_error( err, "dest_me" );
	if( discard_obj )
	{
	    write( "That object has a violent objection to being dested.\n" );
	    write( "Are you sure you want to do this? " );
	    input_to( "no_discard" );
	    return 1;
	}
    }
    if( sizeof( file_names ) > 1 )
	write( COL + "Files discarded sucessfully.%^RESET%^\n" );
    else
	write( COL + "File discarded sucessfully.%^RESET%^\n" );
    return 1;
}

void    no_discard( string s )
{
    string  err;

    if( affirmative( s ) )
    {
	err = catch( discard_obj->dwep() );
	handle_error( err, "DWEP" );
	if( discard_obj )
	{
	    destruct( discard_obj );
	    if( discard_obj )
	    {
		write( "Object could not be destructed.\n" );
		return;
	    }
	}
    }
    write( COL + "Object discarded%^RESET%^.\n" );
    discard_obj = 0;
}


int     load( string str )
{
    string *filenames, err;
    int     loop;

    if( !str )
    {
	notify_fail( "Load what ?\n" );
	return 0;
    }
    filenames = get_cfiles( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( "No such object.\n" );
	return 0;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	if( file_size( str ) < 0 )
	{
	    write( str + ": No such object.\n" );
	    continue;
	}
	if( err = catch( str->load_up_with_yellow() ) )
	    write( COL + "Failed to load " + str +
		   ", error: " + err + "%^RESET%^\n" );
	else
	    write( COL + "Loaded " + str + "%^RESET%^\n" );
    }
    return 1;
}

int     do_more( string str )
{
    object *things, spam;
    int     egg;

    SECURITY

	if( !str )
    {
	notify_fail( "More which file(s)/object?\n" );
	return 0;
    }
    if( sizeof( things = wiz_present( str, this_player() ) ) )
    {
	str = file_name( things[ 0 ] );
	sscanf( str, "%s#%d", str, egg );
	if( file_size( str ) <= 0 )
	    str += ".c";
    }
    return more_file( str );
}


static int edit( string str )
{
    string *filenames, spam, bing;
    object *things;
    int     egg;

    SECURITY

	if( !str )
    {
	in_editor = "(hidden)";
	ed( "frog", "fini_editor" );
	return 1;
    }
    if( sizeof( things = wiz_present( str, this_player() ) ) )
    {
	spam = file_name( things[ 0 ] );
	sscanf( spam, "%s#%d", spam, egg );
	if( file_size( spam ) < 0 )
	    filenames = ({ spam + ".c" });
	else
	    filenames = ({ spam });
    }
    else
	filenames = get_files( str );
    if( !sizeof( filenames ) )
	str = get_path( str );
    else
    {
	if( sizeof( filenames ) > 0 )
	{
	    str = filenames[ 0 ];
	    if( sizeof( filenames ) > 1 )
	    {
		int     loop;

		loop = 0;
		while( loop < sizeof( filenames ) &&
			file_size( filenames[ loop ] ) < 0 )
		{
		    loop++;
		}
		if( loop >= sizeof( filenames ) )
		{
		    write( "No such file.\n" );
		    return 0;
		}
		else
		{
		    str = filenames[ loop ];
		}
		write( "Ambiguous, using : " + str + "\n" );
	    }
	}
    }
    if( file_size( str ) == -2 )
    {
	write( "directory\n" );
	return 1;
    }
    in_editor = str;
    if( !MASTER->valid_write( str, geteuid(), "frog" ) )
	write( "[read only] " );
    else
    {
	spam = (string)CHECKOUT->query_file_owner( str );
	if( spam != "" )
	    if( spam == (string)this_player()->query_cap_name() )
		write( "%^RED%^You have this file checked out currently.%^RESET%^\n" );
	    else
		write( "%^RED%^Warning, this file is checked out by "
		       + spam + ".\nAny changes you make are liable to "
		       + "be over-written.%^RESET%^\n" );
    }
    log_file( "EDITS",
	      (string)this_player()->query_cap_name() + " edited "
	      + str + " on " + ctime( time() ) + "\n" );
    ed( str, "fini_editor" );
    return 1;
}

string  query_in_editor()
{
    return in_editor;
}
void    fini_editor()
{
    in_editor = 0;
}
void    set_in_editor( string str )
{
    in_editor = str;
}

static int clone( string str )
{
    object  ob;
    string  err, *filenames;
    int     loop, mov;

    if( !str )
    {
	notify_fail( "Clone what ?\n" );
	return 0;
    }

    filenames = get_cfiles( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( "No such file.\n" );
	return 0;
    }

    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	if( file_size( str ) < 0 && file_size( str + ".c" ) < 0 )
	{
	    notify_fail( "No such file.\n" );
	    return 0;
	}
/*
   err = catch(ob = clone_object(str));
   handle_error(err, "clone_object()");
 */
	ob = clone_object( str );
	if( ob )
	{
	    err = catch( (mov = (int)ob->move( this_player() )) );
	    handle_error( err, "move(this_player())" );
	    if( err || mov )
	    {
		err = catch( ob->move( environment( this_player() ) ) );
		handle_error( err, "move(environment())" );
	    }
	    write( COL + "Ok.  Object " + file_name( ob ) + " cloned and put in " +
		   (environment( ob ) == this_object()? "you" :
		    (environment( ob ) == environment()? "here" : desc_object( ob ))) +
		   ".%^RESET%^\n" );
	    say( (string)this_player()->query_cap_name() + " creates " +
		 ((string)ob->query_short()?( string ) ob->query_short() : "something") +
		 " out of thin air.\n" );
	}
	else
	    write( COL + "Failed to clone.%^RESET%^\n" );
    }
    return 1;
}

static int what_dir()
{
    write( COL + current_path + "%^RESET%^\n" );
    return 1;
}

static int change_dir( string str )
{
    string *filenames;
    string who;  /* added by Bannor, because Nivek had it */
                 /* in the wrong place :) */

    SECURITY

	if( !str )
    {
	if( !home_dir )
	{
	    notify_fail( "No homedir.  Use homedir to set it.\n" );
	    return 0;
	}
	str = home_dir;
    }
    if( sscanf( str, "~%s", who ) && (who != "/") )
    {
	string rest;

	if( sizeof( explode( who, "/" ) ) > 1 )
	    rest = implode( explode( who, "/" )[ 1..100 ], "/" );
	else
	    rest = "";
	who = explode( who, "/" )[ 0 ];
	who = this_object()->expand_nickname( who );
	str = "~" + who + "/" + rest;
    }
    filenames = get_files( str );
    if( sizeof( filenames ) > 1 )
    {
	notify_fail( "Ambiguous directory.\n" );
	return 0;
    }
    if( !sizeof( filenames ) )
    {
	mixed   ob;
	string *subdirs;

	ob = this_object()->wiz_present( str, this_object() );
	if( sizeof( ob ) )
	{
	    ob = ob[ 0 ];
	    subdirs = explode( file_name( (object)ob ), "/" );
	    str = "/" + implode( subdirs[ 0..sizeof( subdirs ) - 2 ], "/" );
	}
	else
	{
	    notify_fail( "Could not find any object or directory '"
			 + str + "'.\n" );
	    return 0;
	}
    }
    else
	str = filenames[ 0 ];
    if( file_size( str ) != -2 )
	write( COL + "Bad directory : " + str + ".%^RESET%^\n" );
    else
	current_path = str;
    write( COL + current_path + "%^RESET%^\n" );
    return 1;
}

static int exa_file( string str )
{
    string *filenames;
    int     loop;

    SECURITY

	if( !str )
    {
	notify_fail( "Cat what file ?\n" );
	return 0;
    }
    filenames = get_files( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( str + ": No such file.\n" );
	return 0;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	if( sizeof( filenames ) > 1 )
	    write( COL + "FILE : " + str + "%^RESET%^\n" );
	cat( str );
    }
    return 1;
}


static int list_files( string str )
{
    if( !str )
	str = current_path;
    else
	str = get_path( str );
    if( !str )
	return 1;
    ls( str );
    return 1;
}

static int rm_file( string str )
{
    int     fsize, loop;
    string *filenames;

    SECURITY

	if( !str )
    {
	notify_fail( "Usage: rm file [file ...]\n" );
	return 0;
    }
    filenames = get_files( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( "No such file : " + str + "\n" );
	return 0;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	string  temp, file;

	file = filenames[ loop ];
	if( sscanf( file, "%s/.", temp ) || sscanf( file, "%s/..", temp ) )
	    continue;
	fsize = file_size( file );
	if( fsize == -1 )
	{
	    notify_fail( "No such file or directory.\n" );
	    return 0;
	}
	if( fsize == -2 )
	{
	    if( !rmdir( file ) )
	    {
		notify_fail( "Couldn't rm directory: " + file + "\n" );
		return 0;
	    }
	}
	else
	    if( !rm( file ) )
	    {
		notify_fail( "Can't remove file.\n" );
		return 0;
	    }
    }
    if( sizeof( filenames ) > 1 )
	write( COL + "Files removed.%^RESET%^\n" );
    else
	write( COL + "File deleted.%^RESET%^\n" );
    return 1;
}				/* rm_file() */


static int indent_file( string str )
{
    int     fsize, loop;
    string *filenames, temp;

    SECURITY

	if( !str || !stringp( str ) )
    {
	notify_fail( "Usage: indent file\n" );
	return 0;
    }
    filenames = get_files( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( "No such file : " + str + "\n" );
	return 0;
    }
    if( !MASTER->valid_write( filenames[ 0 ], geteuid(), "frog" ) )
    {
	notify_fail( "You don't have write permission to that file.\n" );
	return 0;
    }

    if( sscanf( filenames[ 0 ], "%s/.", temp ) ||
	    sscanf( filenames[ 0 ], "%s/..", temp ) )
    {
	notify_fail( "Usage: indent file\n" );
	return 0;
    }
    fsize = file_size( filenames[ 0 ] );
    if( fsize == -1 )
    {
	notify_fail( "No such file.\n" );
	return 0;
    }
    if( fsize == -2 )
    {
	notify_fail( "Couldn't indent directory: " + filenames[ 0 ] + "\n" );
	return 0;
    }
    else
	if( !indent( filenames[ 0 ] ) )
	{
	    notify_fail( "Can't indent file.  (Not enough memory?)\n" );
	    return 0;
	}

    write( COL + "File indented.%^RESET%^\n" );
    return 1;
}				/* indent_file() */



static int tail_file( string str )
{
    string *filenames;
    int     loop;

    SECURITY

	if( !str )
    {
	notify_fail( "Tail what file ?\n" );
	return 0;
    }
    filenames = get_files( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( str + ": No such file.\n" );
	return 0;
    }
    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	if( sizeof( filenames ) > 1 )
	    write( COL + "FILE : " + str + "%^RESET%^\n" );
	if( !tail( str ) )
	    write( COL + "No such file.%^RESET%^\n" );
    }
    return 1;
}

static int makedir( string str )
{
    SECURITY

	if( !str || str == "" )
    {
	notify_fail( "Make what directory?\n" );
	return 0;
    }
    str = get_path( str );

    if( !str )
	return 1;

    if( file_size( str ) != -1 )
    {
	notify_fail( str + " already exists.\n" );
	return 0;
    }

    if( !mkdir( str ) )
    {
	notify_fail( "Couldn't make dir.\n" );
	return 0;
    }
    write( COL + "Directory made.%^RESET%^\n" );
    return 1;
}


static int removedir( string str )
{
    string *filenames;
    int     fsize, loop;

    SECURITY

	if( !str || str == "" )
    {
	notify_fail( "Remove what dir?\n" );
	return 0;
    }
    filenames = get_files( str );
    if( !sizeof( filenames ) )
    {
	notify_fail( "No such directory : " + str + "\n" );
	return 0;
    }

    for( loop = 0; loop < sizeof( filenames ); loop++ )
    {
	str = filenames[ loop ];
	fsize = file_size( str );
	if( fsize == -1 )
	{
	    notify_fail( str + " doesn't exist.\n" );
	    return 0;
	}
	if( fsize != -2 )
	{
	    notify_fail( str + " is not a directory.\n" );
	    return 0;
	}
	if( !rmdir( str ) )
	{
	    notify_fail( "Couldn't remove dir : " + str + "\n" );
	    return 0;
	}
    }
    write( COL + "Directory removed.%^RESET%^\n" );
    return 1;
}

static int set_home_dir( string str )
{
    SECURITY

	if( str )
	home_dir = get_path( str );
    write( COL + "Home directory set to " + home_dir + ".%^RESET%^\n" );
    return 1;
}

static int execute( string str )
{
    mixed   err, ret;
    object  ob;
    string  file, wiz_dir;

    SECURITY
	if( !this_player() )
	return 0;
    if( !str )
    {
	notify_fail( "Useage : " + query_verb() + " <lpc code>\n" );
	return 0;
    }
    wiz_dir = "/w/" + (string)this_player()->query_name();
    if( file_size( wiz_dir ) != -2 )
    {
	notify_fail( "Directory: " + wiz_dir + " does not exist.\n" );
	return 0;
    }
    file = wiz_dir + "/exec_tmp";
    if( find_object( file ) )
	file->dest_me();
    if( file_size( file + ".c" ) > 0 )
	rm( file + ".c" );
    write_file( file + ".c",
		"create() { seteuid(geteuid(this_player())); }\n" +
		"dest_me() { destruct(this_object()); }\n" +
		"do_call() {\n" + str + ";\n}\n" );
    err = catch( ret = (mixed)file->do_call() );
    if( query_verb() != "qexec" )
	if( err == 0 )
	    printf( "Returns: %O\n", ret );
	else
	    printf( "Error: %s\n", err );
    if( find_object( file ) )
	file->dest_me();
    rm( file + ".c" );
    return 1;
}

int     grep( mixed str )
{
    int     i, j, num;
    string *files, *bit;
    string  s1, s2, s3, s4;

    SECURITY

	num = 1;
    if( sscanf( str, "-n %s", str ) == 1 )
	num = 0;
    if( sscanf( str, "%s -n %s", s1, s2 ) == 2 )
    {
	num = 0;
	str = s1 + " " + s2;
    }
    if( sscanf( str, "%s %s", s1, s2 ) != 2 )
    {
	notify_fail( "Usage: grep pattern <files>\n" );
	return 0;
    }

    files = get_files( s2 );
    if( !sizeof( files ) )
    {
	notify_fail( "File(s) " + s2 + " not found.\n" );
	return 0;
    }
    for( i = 0; i < sizeof( files ); i++ )
	if( file_size( files[ i ] ) > 0 )
	    if( sscanf( read_file( files[ i ] ), "%s" + s1 + "%s", s3, s4 ) == 2 )
	    {
		j = 0;
		str = read_file( files[ i ], 0, 900 );
		write( COL + "File : " + files[ i ] + "%^RESET%^\n" );
		while( str && num )
		{
		    while( sscanf( str, "%s" + s1 + "%s", s3, s4 ) == 2 )
		    {
			bit = explode( s3, "\n" );
			printf( "%4d: %s\n", j + sizeof( bit ), bit[ sizeof( bit ) - 1 ] + s1 +
				explode( s4, "\n" )[ 0 ] );
			j += sizeof( bit );
			str = implode( explode( s4, "\n" )[ 1..1000 ], "\n" );
		    }
		    j = ((j / 900) + 1) * 900;
		    str = read_file( files[ i ], j, 900 );
		}
	    }
    return 1;
}

int     query_ed_setup()
{
    return ed_setup;
}
void    set_ed_setup( int i )
{
    ed_setup = i;
}

int     rec_du( string path )
{
    string *files;
    int     i, size, tot;

    SECURITY

	if( path[ strlen( path ) - 1 ] != '/' )
	path += "/";
    files = get_dir( path + "*" );
    for( i = 0; i < sizeof( files ); i++ )
    {
	if( files[ i ] == "." || files[ i ] == ".." )
	    continue;
	size = file_size( path + files[ i ] );
	if( size > 0 )
	    tot += size;
	else
	    if( size == -2 )
	    {
		printf( "%-30s %5d\n", path + files[ i ],
			(size = rec_du( path + files[ i ] )) );
		tot += size * 1024;
	    }
    }
    return( tot + 1023 ) / 1024;
}

int     du( string str )
{
    SECURITY

	notify_fail( "Must have write access to be allowed to use du on a dir.\n" );
    if( !str )
    {
	if( !"secure/master"->valid_write( current_path, geteuid( this_object() ) ) )
	    return 0;
	printf( "%-30s %5d\n", "Total:", rec_du( current_path ) );
	return 1;
    }
    return 0;
}

int     reg_ex_grep( string str )
{
    string *files;
    string  s1, *s2, *s3, pattern;
    int     i, j, k, fsize;
    int     done;

    SECURITY

	notify_fail( "Usage: grep <pattern> <files>\n" );
    if( !str )
	return 0;

    if( sscanf( str, "%s %s", pattern, str ) != 2 )
	return 0;

    files = get_files( str );
    if( !sizeof( files ) )
    {
	notify_fail( "File(s) " + s2 + " not found.\n" );
	return 0;
    }
    for( i = 0; i < sizeof( files ); i++ )
	if( (fsize = file_length( files[ i ] )) > 0 )
	{
	    done = 0;
	    for( j = 0; j < fsize; j += 500 )
	    {
		s1 = read_file( files[ i ], j, 500 );
		s2 = explode( s1, "\n" );
		s3 = regexp( s2, pattern );
		if( sizeof( s3 ) && !done )
		    printf( "%s\n", files[ i ] );
		for( k = 0; k < sizeof( s3 ); k++ )
		    printf( "%5d: %s\n", j + member_array( s3[ k ], s2 ), s3[ k ] );
	    }
	}
    return 1;
}

int     review()
{
    player::review();
    wiz_info_comm::review();
    return 1;
}

int     do_sar( mixed str )
{
    int     i, j, num;
    string *files, *bit;
    string  s1, s2, s3, s4;

    SECURITY

	if( !str )
    {
	notify_fail( "Usage: sar search_string replace_string <files>\n" );
	return 0;
    }
    s4 = extract( str, 0, 0 );
    if( sscanf( str, s4 + "%s" + s4 + " " + s4 + "%s" + s4 + " %s", s1, s2, s3 ) != 3 )
	if( sscanf( str, "%s %s %s", s1, s2, s3 ) != 3 )
	{
	    notify_fail( "Usage: sar search_string replace_string <files>\n" );
	    return 0;
	}
    files = (string *)this_player()->get_files( s3 );
    if( !sizeof( files ) )
    {
	notify_fail( "File(s) " + s3 + " not found.\n" );
	return 0;
    }
    for( i = 0; i < sizeof( files ); i++ )
    {
	if( file_size( files[ i ] ) <= 0 )
	    continue;
	write( "Looking at " + files[ i ] + ".\n" );
	s4 = read_file( files[ i ] );
	if( s4 )
	{
	    s4 = replace( s4, s1, s2 );
	    rm( files[ i ] );
	    write_file( files[ i ], s4 );
	}
	else
	    write( COL + "File not found.%^RESET%^\n" );
    }
    return 1;
}

int     backup_file( string str )
{
    int     i;
    string  file, date;

    SECURITY

	if( !str )
    {
	notify_fail( "Useage : backup <filename>\n" );
	return 0;
    }
    if( file_size( str ) < 0 )
	str = (string)this_player()->query_current_path() + "/" + str;
    if( file_size( str ) < 0 )
    {
	notify_fail( "Cannot find file to backup.\n" );
	return 0;
    }
    date = ctime( time() );
    i = member_array( date[ 4..6 ],
		      ({ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" })
		       );
    i++;
    date = date[ 22..23 ] + i + date[ 8..9 ];
    if( strlen( date ) == 5 )
	date = date[ 0..1 ] + "0" + date[ 2..4 ];
    date = replace( date, " ", "0" );
    if( file_size( str + "." + date ) != -1 )
    {
	i = 2;
	while( file_size( str + "." + date + "v" + i ) != -1 )
	    i++;
	date += "v" + i;
    }
    file = read_file( str );
    write_file( str + "." + date, file );
    write( COL + "File backed up to " + str + "." + date + "%^RESET%^\n" );
    return 1;
}

int     do_owner( string str )
{
    return( int ) CHECKOUT->whois_owner( str );
}

int     do_checkout( string str )
{
    return( int ) CHECKOUT->check_file_out( str );
}

int     do_return( string str )
{
    return( int ) CHECKOUT->return_file( str );
}

int     do_filesout( string str )
{
    return( int ) CHECKOUT->query_owners_files( str );
}