skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * securitytool.c
 * The Security Control Tool
 * for the admtool
 * Shaydz 2 Apr '00
 */

#include <colors.h>
inherit COMMAND_BASE;

#define MAIL_FILE "/doc/creator/concepts/creator_doc.txt"
#define IDLE_APP  "/d/admin/text/idle_app.txt"
#define PRIVILEGE(XXX) PRIVILEGE_H->query_privilege(XXX,TP->query_name())

private mapping return_mapping = ([ ]);
private string main_menu_template = @END
-------------------------------------------------------------------------
%s
-------------------------------------------------------------------------
  %sCommand                                      Status%s

  [1]  Promote new creator                     %s
  [2]  Demote creator                          %s
  [3]  Suspend player                          %s
  [4]  Unsuspend player                        %s
  [5]  Banish Player                           %s
  [6]  Grant Privilege                         %s
  [7]  Revoke Privilege                        %s
  [8]  List creators privileges                %s
  [9]  List all privileges in system           %s

END;

private string main_prompt = "Enter your command [1-9], or [Q] to quit: ";
private string main_prompt2 = "Enter your command [1-9], [B] to go back, or [Q] to quit: ";

// Function prototypes
mixed cmd(string args);
private void get_command( string str );
private void promote_creator();
private void promote_creator2( string str );
private void promote_creator3( string str, string domain );
private void demote_creator();
private void demote_creator2( string str);
private void demote_creator3( string reason, string str );
private void demote_creator4( string str, string crea, string reason );
private void suspend_player();
private void suspend_player2( string str );
private void suspend_player3( string str, string str2 );
private void unsuspend_player();
private void unsuspend_player2( string str );
private void unsuspend_player3( string str, string str2 );
private void banish_player();
private void banish_player2( string str );
private void banish_player3( string str, string pname );
private void banish_player4( string str, string pname );
private void banish_player5( string str, string pname, string reason );
private void grant_privilege();
private void grant_privilege2( string str );
private void grant_privilege3( string str, string str2 );
private void revoke_privilege();
private void revoke_privilege2( string str );
private void revoke_privilege3( string str, string str2 );
private void list_cre_privileges();
private void list_cre_privileges2( string str );
private void list_cre_privileges3( string args );
private void list_all_privileges();
private void list_all_privileges2( string str );

private void display_menu() {
    string title, s1, s2, s3, s4, s5, s6, s7, s8, s9;

    title = sprintf("%s%|72s%s", YELLOW,
        mud_name()+" Security Control Tool v1.5", RESET );

    s1 = s2 = s3 = s4 = s5 =  s6 = s7 = s8 = s9 = RED+"Unavailable"+RESET;

    if( PRIVILEGE("creator.add") )
        s1 = GREEN+"Available"+RESET;

    if( PRIVILEGE("creator.remove") )
        s2 = GREEN+"Available"+RESET;

    if( PRIVILEGE("player.suspend") )
        s3 = GREEN+"Available"+RESET;

    if( PRIVILEGE("player.unsuspend") )
        s4 = GREEN+"Available"+RESET;

    if( PRIVILEGE("player.banish") )
        s5 = GREEN+"Available"+RESET;

    if( PRIVILEGE("privilege.add") )
        s6 = GREEN+"Available"+RESET;

    if( PRIVILEGE("privilege.remove") )
        s7 = GREEN+"Available"+RESET;

    if( adminp(TP) )
        s8 = GREEN+"Available"+RESET;

    if( adminp(TP) )
        s9 = GREEN+"Available"+RESET;

    tell_object( TP, sprintf( main_menu_template, title, BOLD, RESET,
                 s1, s2, s3, s4, s5, s6, s7, s8, s9 ) );

} /* display_menu() */

private void do_prompt() {
    tell_object( TP, undefinedp(return_mapping[TP]) ? main_prompt :
                                                      main_prompt2 );
    input_to( (: get_command :) );
} /* do_prompt() */

private void promote_creator() {
    if( !PRIVILEGE("creator.add") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+
            RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the player to promote: ");
    input_to( (: promote_creator2 :) );

} /* promote_creator() */

private void promote_creator2( string str ) {
    if( !str || str == "")
        return do_prompt();

    if( !LOGIN_OBJ->test_user(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" isn't a player here.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "What domain should "+CAP(str)+" start in? "
        "[press enter for learning] : ");
    input_to( (: promote_creator3( $1, $(str) ) :) );

} /* promote_creator2() */

private void promote_creator3( string str, string crea ) {
    string err, old;

    if( !str || str == "" )
        str = "learning";

    if( !DOMAIN_H->query_domain(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" isn't a valid domain, putting "
            "them in Learning.\n"+RESET );
        str = "learning";
    }

    old = geteuid(TO);
    seteuid(geteuid(TP));

    if( !err = DOMAIN_H->add_creator(crea) ) {
        DOMAIN_H->add_member( str, crea );

        if( file_exists(MAIL_FILE) ) {
            string body = read_file(MAIL_FILE);
            MAIL_H->do_mail_message( crea, TP->query_name(),
                "How to get started.", "", body, 0, 0 );
        }

        tell_object( TP, GREEN+"\n"+CAP(crea)+" has been promoted.\n"+RESET );
        event( users(), "inform", TP->query_cap_name()+" has promoted "+
            CAP(crea)+".", "admin");
    } else {
        tell_object( TP, RED+"\nUnable to promote "+CAP(crea)+" because: "+
            err+"\n"+RESET );
    }

    seteuid(old);

    return do_prompt();

} /* promote_creator3() */

private void demote_creator() {
    if( !PRIVILEGE("creator.remove") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+
            RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the creator to demote: ");
    input_to( (: demote_creator2 :) );

} /* demote_creator() */

private void demote_creator2( string str ) {
    if( !str || str == "")
        return do_prompt();

    if( !creatorp(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" isn't a creator here.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "Please enter a reason for demoting "+CAP(str)+".\n"
        "\"idle app\" for idle apprentices: ");
    input_to( (: demote_creator3( $1, $(str) ) :) );

} /* demote_creator2() */

private void demote_creator3( string reason, string str ) {
    if( !reason || reason == "")
        return do_prompt();

    tell_object( TP, "Are you sure you wish to demote "+CAP(str)+": ");
    input_to( (: demote_creator4( $1, $(str), $(reason) ) :) );

} /* demote_creator2() */

private void demote_creator4( string str, string crea, string reason ) {
    string err, old;

    if( !str || str == "")
        return do_prompt();

    str = lower_case(str);

    if( str != "y" && str != "yes")
        return do_prompt();

    old = geteuid(TO);
    seteuid(geteuid(TP));

    if( !err = DOMAIN_H->remove_creator( crea+" "+reason ) ) {
        tell_object( TP, GREEN+"\n"+CAP(crea)+" has been demoted.\n"+RESET );
        event( users(), "inform", TP->query_cap_name()+" has demoted "+
            CAP(crea)+" for "+reason+".", "admin");
        if( reason == "idle app" && file_exists(IDLE_APP) ) {
            string body = read_file(IDLE_APP);
            body = replace( body, "$cre$", TP->query_cap_name() );
            MAIL_H->do_mail_message( crea, TP->query_name(),
                "Your demotion.", "", body, 0, 0 );
        }
    } else {
        tell_object( TP, RED+"\nUnable to demote "+CAP(crea)+" because: "+
            err+"\n"+RESET );
    }

    seteuid(old);

    return do_prompt();

} /* demote_creator3() */

private void suspend_player() {
    if( !PRIVILEGE("player.suspend") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+
            RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the player to suspend: ");
    input_to( (: suspend_player2 :) );

} /* suspend_creator() */

private void suspend_player2( string str ) {
    if( !str || str == "")
        return do_prompt();

    if( !LOGIN_OBJ->test_user(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" isn't a player here.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "How many hours do you wish to suspend "+
        CAP(str)+" for? : ");
    input_to( (: suspend_player3( $1, $(str) ) :) );

} /* suspend_player2() */

private void suspend_player3( string str, string str2 ) {
    int tim;

    if( !str || str == "")
        return do_prompt();

    tim = to_int(str);

    if( !BASTARDS_H -> suspend_person( str2, tim*60*60 ) ) {
        tell_object( TP, RED+"\nSuspension not accepted.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, CAP(str2)+" suspended until "+
        ctime(time()+tim*60*60)+"\n");

    return do_prompt();

} /* suspend_player3() */

private void unsuspend_player() {
    if( !PRIVILEGE("player.unsuspend") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+
            RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the player to unsuspend: ");
    input_to( (: unsuspend_player2 :) );

} /* unsuspend_player() */

private void unsuspend_player2( string str ) {
    if( !str || str == "")
        return do_prompt();

    if( !PLAYER_H->test_user(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" isn't a player here.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "Are you sure you wish to unsuspend "+CAP(str)+"? : ");
    input_to( (: unsuspend_player3( $1, $(str) ) :) );

} /* unsuspend_player2() */

private void unsuspend_player3( string str, string str2 ) {
    str = lower_case(str);

    if( !str || str == "")
        return do_prompt();

    if( str != "y" && str != "yes")
        return do_prompt();

    if( !BASTARDS_H->unsuspend_person(str2) ) {
        tell_object( TP, RED+"\nYou don't have access to do that.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP,GREEN+"\n"+CAP(str2) +" unsuspended.\n"+RESET );
    return do_prompt();

} /* unsuspend_player3() */

private void banish_player() {
    if( !PRIVILEGE("player.banish") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the player to banish: ");
    input_to( (: banish_player2 :) );

} /* banish_player() */

private void banish_player2( string str ) {
    if( !str || str == "")
        return do_prompt();

    str = lower_case( str ) ;

    if( creatorp(str) ) {
        tell_object( TP, RED+"\nYou cannot banish creators, please demote "
            "them first.\n"+RESET );
        return do_prompt();
    }

    if( file_exists("/banish/"+str[0..0]+"/"+str+".o") ) {
        tell_object( TP, RED+"\nThe name ["+str+"] has already been "
            "banished.\n"+RESET );
        return do_prompt();
    }

    if( file_exists("/save/banish/"+str+".o") ) {
        tell_object( TP, "The name ["+str+"] has already been backed up.  "
            "Please remove the file first from /save/banish/.\n"+RESET );
        return do_prompt();
    }

    if( file_exists("/save/players/"+str[0..0]+"/"+str+".o") ) {
        tell_object( TP, "Are you sure you wish to banish "+CAP(str)+": ");
        input_to( (: banish_player3( $1, $(str) ) :) );
        return;
    }

    tell_object( TP, "The player file does not exist, continue ? [Y/N] : ");
    input_to( (: banish_player3( $1, $(str) ) :) );
    return;

} /* banish_player2() */

private void banish_player3( string str, string pname ) {
    str = lower_case(str);

    if( !str || str == "")
        return do_prompt();

    if( str == "y") {
        tell_object( TP, "Please enter a reason: ");
        input_to( (: banish_player4( $1, $(pname) ) :) );
        return;
    }

    tell_object( TP, RED+"\nAborting banish process.\n"+RESET );
    return do_prompt();

} /* banish_player3() */

private void banish_player4( string str, string pname ) {
    if( !str || str == "") {
        tell_object( TP, RED+"\nAborting banish process.\n"+RESET );
        return do_prompt();
    }

    if( file_exists("/save/players/"+pname[0..0]+"/"+pname+".o") ) {
        tell_object( TP, "Do you want to remove the old player file? [Y/N] : ");
        input_to( (: banish_player5( $1, $(pname), $(str) ) :) );
        return;
    }

    tell_object( TP, GREEN+ "\nOkay, "+CAP(pname)+" banished.\n"+RESET );
    return do_prompt();

} /* banish_player4() */

private void banish_player5( string str, string pname, string reason ) {
    string old;

    str = lower_case(str);

    if( !str || str == "")
        return do_prompt();

    reason = "Banished by : "+TP->query_cap_name()+"\n"
             "Banished on : "+ctime( time() )+"\n"
             "Reason      : "+reason+"\n";

    old = geteuid(TO);
    seteuid(geteuid(TP));

    if( str == "y") {
        unguarded( (: rm, "/save/players/"+pname[0..0]+"/"+pname+".o" :) );

        BULK_DELETE_H->delete_related_files( pname, 1 );

        write_file("/banish/"+pname[0..0]+"/"+pname+".o", reason );

        seteuid(old);

        tell_object( TP, "Okay, player banished and save file removed.\n"+
            RESET );

        return do_prompt();
    }

    if( !dir_exists("/save/banish/") )
        unguarded( (: mkdir, "/save/banish" :) );

    unguarded( (: rename, "/save/players/"+pname[0..0]+"/"+pname+".o",
        "/save/banish/"+pname+".o" :) );

    write_file("/banish/"+pname[0..0]+"/"+pname+".o", reason );

    seteuid(old);

    tell_object( TP, "Okay, player banished and playerfile backed up.\n");

    return do_prompt();

} /* banish_player5() */

private void grant_privilege() {
    if( !PRIVILEGE("privilege.add") ) {
        tell_object( TP,RED+"\nYou don't have the power to do that.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the privilege to grant "
        "(eg. creator.add) : ");
    input_to( (: grant_privilege2 :) );

} /* grant_privilege() */

private void grant_privilege2( string str ) {
    if( !str || str == "")
        return do_prompt();

    // Need something here to check whether this privilege is valid at all.
    tell_object( TP, "What player do you want to add the privilege "+
        str+" to: ");
    input_to( (: grant_privilege3( $1, $(str) ) :) );

} /* grant_privilege2() */

private void grant_privilege3( string str, string str2 ) {
    string err, old;

    if( !str || str == "")
        return do_prompt();

    old = geteuid(TO);
    seteuid(geteuid(TP));

    if( !err = PRIVILEGE_H->add_privilege( str2, str ) ) {
        tell_object( TP, GREEN+"\nAdded privilege "+str2+" to "+
            CAP(str)+".\n\n"+RESET );
        seteuid(old);
        return do_prompt();
    }

    tell_object( TP, RED+"\nFailed to add privilege "+str2+" to "+
        CAP(str)+" because: "+err+"\n"+RESET );

    seteuid(old);

    return do_prompt();

} /* grant_privilege3() */

private void revoke_privilege() {
    if( !PRIVILEGE("privilege.remove") ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the privilege to revoke "
        "(eg. creator.add) : ");
    input_to( (: revoke_privilege2 :) );

} /* revoke_privilege() */

private void revoke_privilege2( string str ) {
    if( !str || str == "")
        return do_prompt();

    tell_object( TP, "What player do you want to remove the privilege "+
        str+" from: ");
    input_to( (: revoke_privilege3($1, $(str)) :) );

} /* revoke_privilege2() */

private void revoke_privilege3( string str, string str2 ) {
    string err, old;

    if( !str || str == "")
        return do_prompt();

    old = geteuid(TO);
    seteuid(geteuid(TP));

    if( !err = PRIVILEGE_H->remove_privilege( str2, str ) ) {
        tell_object( TP, GREEN+"\nRemoved privilege "+str2+" from "+
            CAP(str)+".\n\n"+RESET );
    } else {
        tell_object( TP, RED+"\nFailed to remove privilege "+str2+" from "+
            CAP(str)+" because: "+err+"\n"+RESET );
    }

    seteuid(old);

    return do_prompt();

} /* revoke_privilege3() */

private void list_cre_privileges() {
    if( !adminp(TP) ) {
        tell_object( TP, RED+"\nYou don't have the power to do that.\n"+
            RESET );
        return do_prompt();
    }

    tell_object( TP, "Enter the name of the creator to view.  Press 'enter' "
        "to view all creators or type 'nosages' to exclude sages from the "
        "list: ");
    input_to( (: list_cre_privileges2 :) );

} /* list_cre_privileges() */

private void list_cre_privileges2( string str ) {
    string *ret;

    if( !str || str == "") {
        list_cre_privileges3("all");
        return;
    }

    if( str == "nosages") {
        list_cre_privileges3("nosages");
        return;
    }

    if( adminp(str) ) {
        if( str == TP->query_name() ) {
            tell_object( TP, GREEN+"\nYou are an admin, and have all "
                "privileges.\n"+RESET );
        } else {
            tell_object( TP, GREEN+"\n"+CAP(str)+" is an admin, and has all "
                "privileges.\n"+RESET );
        }
        return do_prompt();
    }

    if( !creatorp(str) ) {
        tell_object( TP, RED+"\n"+CAP(str)+" is not a creator.\n"+RESET );
        return do_prompt();
    }

    ret = PRIVILEGE_H->query_privileges(str);

    if( !sizeof(ret) ) {
        tell_object( TP, GREEN+"\n"+CAP(str)+" does not have any "
            "privileges.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, sprintf("%s\n%s has the following privileges:%s%s\n"
        "%-*#s%s\n\n", GREEN, CAP(str), RESET, YELLOW, 79,
        implode( sort_array( ret, 1 ), "\n"), RESET ) );

    return do_prompt();

} /* list_cre_privileges2() */

private void list_cre_privileges3( string args ) {
    string *ret, *creas, str;

    creas = DOMAIN_H->query_creators();

    if( args == "nosages")
        creas -= DOMAIN_H->query_members("sage");

    creas = asort(creas);

    if( !creas ) {
        tell_object( TP, RED+"\nThere don't appear to be any creators!!!\n"+
            RESET );
        return do_prompt();
    }

    args = "";

    foreach( str in creas ) {
        ret = PRIVILEGE_H->query_privileges(str);

        if( !sizeof(ret) && !adminp(str) )
            continue;

        args += GREEN+"\n"+CAP(str)+":\n"+YELLOW;

        if( adminp(str) ) {
            if( str == TP->query_name() ) {
                args += "You are an admin, and have all privileges.\n";
            } else {
                args += CAP(str)+" is an admin, and has all privileges.\n";
            }
            args += RESET;
            continue;
        }

        if( !creatorp(str) ) {
            args += RED+"\n"+CAP(str)+" is not a creator.\n"+RESET;
            continue;
        }

        args += sprintf("%-*#s%s\n", 79,
            implode( sort_array( ret, 1 ), "\n"), RESET );

    }

    tell_object( TP, args+"\n");
    return do_prompt();

} /* list_cre_privileges3() */

private void list_all_privileges() {
    string *ret;

    if( !adminp(TP) ) {
        tell_object( TP, RED+"\nYou don't have the power to use this "
            "option.\n"+RESET );
        return do_prompt();
    }

    ret = PRIVILEGE_H->query_privilege_types();

    if( !ret ) {
        tell_object( TP, GREEN+"\nThere have been no privileges "
            "assigned.\n"+RESET );
        return do_prompt();
    }

    tell_object( TP, sprintf("%s\nThe following privileges have been entered "
        "into the system:\n%s%s%-*#s\n", GREEN, RESET, YELLOW, 79,
        implode( sort_array( ret, 1 ), "\n") )+"\n"+RESET );

    return do_prompt();

} /* list_all_privileges() */

private void get_command( string str ) {
    if( !str ) {
        display_menu();
        return do_prompt();
    }

    switch( str ) {
      case "1":
        promote_creator();
      break;
      case "2":
        demote_creator();
      break;
      case "3":
        suspend_player();
      break;
      case "4":
        unsuspend_player();
      break;
      case "5":
        banish_player();
      break;
      case "6":
        grant_privilege();
      break;
      case "7":
        revoke_privilege();
      break;
      case "8":
        list_cre_privileges();
      break;
      case "9":
        list_all_privileges();
      break;
      case "B":
      case "b":
        if( !return_mapping[TP] ) {
            display_menu();
            return do_prompt();
        }
        return_mapping[TP]->cmd("");
        map_delete( return_mapping, TP );
      break;
      case "Q":
      case "q":
        map_delete( return_mapping, TP );
      break;
      default:
        display_menu();
        return do_prompt();
    }

} /* get_command() */

int cmd( string arg ) {
    if( PO && file_name(PO) == "/secure/cmds/creator/admtools")
        return_mapping[TP] = PO;

    if( !lordp(TP) ) {
        log_file("SECURITY_VIOLATION", TP->query_name()+" attempted to "
            "illegally use the SecurityTool on "+ctime(time())+"\n");
        return notify_fail("%^RED%^Security Violation!\n%^RESET%^");;
    }

    display_menu();
    do_prompt();

    return 1;

} /* cmd() */