/* MASTER_NAME (#define in config.h, or as commandline option) ** obj/master.c (compat default) ** secure/master.c (native default) ** ** The master is the gateway between the gamedriver and the mudlib to perform ** actions with mudlib specific effects. ** Calls to the master by the gamedriver have an automatic catch() in effect. ** ** This skeleton names all functions called by the gamedriver and gives ** suggestions on how to program then (a few by code). ** Functions which are specific to compat or native mode are tagged as such: ** '// !compat' means: only when not running in compat mode. ** '// native' means: only when running in native mode. ** and similar for every other combination. ** ** Note that the master is loaded first of all objects. Thus it is possible, ** you shouldn't inherit an other object (as most files expect the master ** to exist), nor is the compiler able to search include files ** (read: they must be specified with full path). */ // A short reference to all functions... //--------------------------------------------------------------------------- // Initialisation // // void inaugurate_master (int arg) // Perform mudlib specific setup of the master. // // string get_master_uid () // Return the string to be used as uid (and -euid) of a (re)loaded master. // // void flag (string arg) // Evaluate an argument given as option '-f' to the driver. // // string *epilog (int eflag) // Perform final actions before opening the game to players. // // void preload (string file) // Preload a given object. // // void external_master_reload () // Called after a reload of the master on external request. // // void reactivate_destructed_master (int removed) // Reactivate a formerly destructed master. // // string|string * get_simul_efun () // Load the simul_efun object(s) and return one or more paths of it. // //--------------------------------------------------------------------------- // Handling of player connections // // object connect () // Handle the request for a new connection. // // void disconnect (object obj, string remaining) // Handle the loss of an IP connection. // // void remove_player (object player) // Remove a player object from the game. // // void stale_erq (closure callback) // Notify the loss of the erq demon. //--------------------------------------------------------------------------- // Runtime Support // // object compile_object (string filename) // Compile an virtual object. // // string get_wiz_name (string file) // Return the author of a file. // // mixed include_file (string file, string compiled_file, int sys_include) // Return the full pathname for an included file. // // mixed inherit_file (string file, string compiled_file) // Return the full pathname for an inherited object. // // string printf_obj_name (object obj) // Return a printable name for an object. // // mixed prepare_destruct (object obj) // Prepare the destruction of the given object. // // void quota_demon (void) // Handle quotas in times of memory shortage. // // void receive_udp (string host, string msg, int port) // Handle a received UDP message. // // void slow_shut_down (int minutes) // Schedule a shutdown for the near future. // // void notify_shutdown (void|string crash_reason) // Notify the master about an immediate shutdown. // //--------------------------------------------------------------------------- // Error Handling // // void dangling_lfun_closure () // Handle a dangling lfun-closure. // // void log_error (string file, string err, int warn) // Announce a compiler-time error or warning. // // mixed heart_beat_error (object culprit, string err, // string prg, string curobj, int line, // int caught ) // Announce an error in the heart_beat() function. // // void runtime_error (string err, string prg, string curobj, int line // , mixed culprit, int caught) // Announce a runtime error. // // void runtime_warning (string msg, string curobj, string prg, int line // , int inside_catch) // Announce a runtime warning. // //--------------------------------------------------------------------------- // Security and Permissions // // int privilege_violation (string op, mixed who, mixed arg, mixed arg2) // Validate the execution of a privileged operation. // // int query_allow_shadow (object victim) // Validate a shadowing. // // int valid_trace (string what, int|string arg) // Check if the player may use tracing. // // int valid_exec (string name, object ob, object obfrom) // Validate the rebinding of an IP connection by usage of efun exec(). // // int valid_query_snoop (object obj) // Validate if the snoopers of an object may be revealed by usage of the // efun query_snoop(). // // int valid_snoop (object snoopee, object snooper) // Validate the start/stop of a snoop. // //--------------------------------------------------------------------------- // Userids and depending Security // // string get_bb_uid() // Return the string to be used as temporary euid by process_string(). // // int valid_seteuid (object obj, string neweuid) // Validate the change of an objects euid by efun seteuid(). // // int|string valid_read (string path, string euid, string fun, object caller) // int|string valid_write (string path, string euid, string fun, object caller) // Validate a reading/writing file operation. // //--------------------------------------------------------------------------- // ed() Support // // string make_path_absolute (string str) // Absolutize a relative filename given to the editor. // // int save_ed_setup (object who, int code) // Save individual settings of ed for a wizard. // // int retrieve_ed_setup (object who) // Retrieve individual settings of ed for a wizard. // // string get_ed_buffer_save_file_name (string file) // Return a filename for the ed buffer to be saved into. // //--------------------------------------------------------------------------- // parse_command() Support (!compat, SUPPLY_PARSE_COMMAND defined) // // string *parse_command_id_list () // Return generic singular ids. // // string *parse_command_plural_id_list () // Return generic plural ids. // // string *parse_command_adjectiv_id_list () // Return generic adjective ids. // // string *parse_command_prepos_list () // Return common prepositions. // // string parse_command_all_word() // Return the one(!) 'all' word. // //--------------------------------------------------------------------------- //=========================================================================== // Initialisation // // These functions are called after (re)loading the master to establish the // most basic operation parameters. // // The initialisation of LPMud on startup follows this schedule: // - The gamedriver evaluates the commandline options and initializes // itself. // - The master is loaded, but since the driverhooks are not set yet, // no standard initialisation lfun is called. // - get_master_uid() is called. If the result is valid, it becomes the // masters uid and euid. // - inaugurate_master() is called. // - flag() is called for each given '-f' commandline option. // - get_simul_efun() is called. // - the WIZLIST is read in. // - epilog() is called. If it returns an array of strings, they are given // one at a time as argument to preload(). // Traditionally, these strings are the filenames of the objects to // preload, which preload() then does. // - The gamedriver sets up the IP communication and enters the backend // loop. // // If the master is reloaded during the game, this actions are taken: // - The master is loaded, and its initialisation lfun is called according // to the settings of the driverhooks (if set). // - Any auto-include string and all driverhooks are cleared. // - get_master_uid() is called. If the result is valid, it becomes the // masters uid and euid. // - inaugurate_master() is called. // // If the master was destructed, but couldn't be reloaded, the old // master object could be reactivated. In that case: // - reactivate_destructed_master() is called. // - inaugurate_master() is called. //=========================================================================== //--------------------------------------------------------------------------- // Initialization of the master object. // // As the lfuns which are called to initialize objects after a load are // defined through driver hooks, and these hooks are cleared prior to // a master (re)load, the first function called is inaugurate_master(). // Anyway it's not very sensible to do anything earlier as the master is // not recognized as such at that time, and so a number of (important) things // would not work. // // Which lfun is called during runtime to reset the master is also depending // on the driverhook settings. Arbitrary actions may be done on a reset. //--------------------------------------------------------------------------- void inaugurate_master (int arg) // Perform mudlib specific setup of the master. // // Argument: // arg: 0 if the mud just started. // 1 if the master is reactivated destructed one. // 2 if the master is a reactivated destructed one, which lost all // variables. // 3 if the master was just reloaded. // // This function is called whenever the master becomes fully operational // after (re)loading (it is now recognized as _the_ master). // This doesn't imply that the game is up and running. // // This function has at least to set up the driverhooks to use. Also, any // mudwho or wizlist handling has to be initialized here. // // Besides that, do whatever you feel you need to do, // e.g. set_driver_hook(), or give the master a decent euid. //--------------------------------------------------------------------------- int|string get_master_uid () // Return the string to be used as uid (and -euid) of a (re)loaded master. // Under !native, the function may also return a non-zero number. // In that case, the uid is set to 0, as is the euid. //--------------------------------------------------------------------------- void flag (string arg) // Evaluate an argument given as option '-f' to the driver. // // Arguments: // arg: The argument string from the option text '-f'. // If several '-f' options are given, this function // will be called sequentially with all given arguments. // // This function can be used to pass the master commands via arguments to // the driver. This is useful when building a new mudlib from scratch. // It is called only when the game is started. // // The code given implements these commands: // '-fcall ': call function in object with // argument . // '-fshutdown': shutdown the game immediately. // Thus, starting the game as 'parse "-fcall foo bar Yow!" -fshutdown' would // first do foo->bar("Yow!") and then shutdown the game. { string obj, fun, rest; if (arg == "shutdown") { shutdown(); return; } if (sscanf(arg, "call %s %s %s", obj, fun, rest) >= 2) { write(obj+"->"+fun+"(\""+rest+"\") = "); write(call_other(obj, fun, rest)); write("\n"); return; } write("master: Unknown flag "+arg+"\n"); } //--------------------------------------------------------------------------- string *epilog (int eflag) // Perform final actions before opening the game to players. // // Arguments: // eflag: This is the number of '-e' options given to the parser. // Normally it is just 0 or 1. // // Result: // An array of strings, which traditionally designate the objects to be // preloaded with preload(). // Any other result is interpreted as 'no object to preload'. // The resulting strings will be passed one at the time as // arguments to preload(). //--------------------------------------------------------------------------- void preload (string file) // Preload a given object. // // Arguments: // file: The filename of the object to preload, as returned by epilog(). // // It is task of the epilog()/preload() pair to ensure the validity of // the given strings (e.g. filtering out comments and blank lines). // For preload itself a 'load_object(file)' is sufficient, but it // should be guarded by a catch() to avoid premature blockings. // Also it is wise to change the master's euid from master_uid to something // less privileged for the time of the preload. // // You can of course do anything else with the passed strings - preloading // is just the traditional task. //--------------------------------------------------------------------------- void external_master_reload () // Master was reloaded on external request by SIGUSR1. // // If the gamedriver destruct and reloads the master on external request // via SIGUSR1, it does this by a call to this function. // It will be called after inaugurate_master() of course. // If you plan to do additional magic here, you're welcome. //--------------------------------------------------------------------------- void reactivate_destructed_master (int removed) // Reactivate a formerly destructed master. // // Arguments: // removed: True if the master was already on the list of destructed // objects. // // This function is called in an formerly destructed master since a new master // couldn't be loaded. // This function has to reinitialize all variables at least to continue // operation. //--------------------------------------------------------------------------- string|string * get_simul_efun () // Load the simul_efun object(s) and return one or more paths of it. // // Result: // Either a single string with the file_name() of the simul_efun object, // or an array of strings which has to start with that file_name(). // Return 0 if this feature isn't wanted. // // Note that the object(s) must be loaded by this function! // // When you return an array of strings, the first string is taken as path // to the simul_efun object, and all other paths are used for backup // simul_efun objects to call simul_efuns that are not present in the // main simul_efun object. This allows to remove simul_efuns at runtime // without getting errors from old compiled programs that still use the // obsolete simul_efuns. // // The additional simul-efun objects can not serve as backups for // the primary one! // // If the game depends on the simul_efun object, and none could be loaded, // an immediate shutdown should occur. //=========================================================================== // Handling of player connections // // See also valid_exec(). //=========================================================================== //--------------------------------------------------------------------------- object connect () // Handle the request for a new connection. // // Result: // An login object the requested connection should be bound to. // // Note that the connection is at this time bound to the master object, // and will be re-bound to the returned object. // // The gamedriver will call the lfun 'logon()' in the login object after // binding the connection to it. That lfun has to return !=0 to succeed. // // If connect() initiates a secure connection without setting a callback, // and the connection is still handshaking at the time connect() returns, // the driver will delay the call to logon() until the handshake either // succeeds or fails. //--------------------------------------------------------------------------- void disconnect (object obj, string remaining) // Handle the loss of an IP connection. // // Argument: // obj: The (formerly) interactive object (player). // remaining: The remaining unprocessed input data from the connection. // // This called by the gamedriver to handle the removal of an IP connection, // either because the connection is already lost ('netdeath') or due to // calls to exec() or remove_interactive(). // // The connection will be unbound upon return from this call, so // for the time of this call, interactive(ob) will still return TRUE // even if the actual network connection has already been lost. // // This method is not called if the object has been destructed already. //--------------------------------------------------------------------------- void remove_player (object player) // Remove a player object from the game. // // Argument: // player: The player object to be removed. // // This function is called by the gamedriver to expell remaining players // from the game on shutdown in a polite way. // If this functions fails to quit/destruct the player, it will be // destructed the hard way by the gamedriver. // // Note: This function must not cause runtime errors. //--------------------------------------------------------------------------- void stale_erq (closure callback) // Notify the loss of the erq demon. // // Argument: // callback: the callback closure set for an erq request. // // If the erq connection dies prematurely, the driver will call this lfun for // every pending request with set callback. This function should notify the // originating object that the answer will never arrive. //=========================================================================== // Runtime Support // // Various functions used to implement advanced runtime features. //=========================================================================== //--------------------------------------------------------------------------- object compile_object (string filename) // Compile an virtual object. // // Arguments: // previous_object(): The object requesting the virtual object. // filename : The requested filename for the virtual object. // // Result: // The object to serve as the requested virtual object, or 0. // // This function is called if the compiler can't find the filename for an // object to compile. The master has now the opportunity to return an other // which will then serve as if it was compiled from . // If the master returns 0, the usual 'Could not load'-error will occur. //--------------------------------------------------------------------------- mixed include_file (string file, string compiled_file, int sys_include) // Generate the pathname of an included file. // // Arguments: // previous_object(): The object causing the compile. // file : The name given in the #include directive. // compiled_file : The object file which is just compiled // (compat: name without leading "/"). // sys_include : TRUE for #include <> directives. // // Result: // 0: use the normal include filename generation (""-includes are used // as they are, <>-includes are handled according to H_INCLUDE_DIRS). // : the full absolute pathname of the file to include without // parentdir parts ("/../"). Leading slashes ("/") may be omitted. // else: The include directive is not legal. //--------------------------------------------------------------------------- mixed inherit_file (string file, string compiled_file) // Generate the pathname of an inherited file. // // Arguments: // previous_object(): The object causing the compile. // file : The name given in the inherit directive. // compiled_file : The object file which is just compiled // (compat: name without leading "/"). // // Result: // 0: use the filename as it is. // : the full absolute pathname of the file to inherit without // parentdir parts ("/../"). Leading slashes ("/") are ignored. // else: The include directive is not legal. //--------------------------------------------------------------------------- string get_wiz_name (string file) // Return the author of a file. // // Arguments: // file: The name of the file in question. // // Result: // The name of the file's author (or 0 if there is none). // // This function is called for maintenance of the wiz-list, to score errors // to the right wizard. //--------------------------------------------------------------------------- string printf_obj_name (object obj) // Return a printable name for an object. // // Arguments: // obj: The object which name is of interest. // // Result: // A string with the objects name, or 0. // // This function is called by sprintf() to print a meaningful name // in addition to the normal object_name(). // If this functions returns a string, the object will be printed // as " ()". //--------------------------------------------------------------------------- mixed prepare_destruct (object obj) // Prepare the destruction of the given object. // // Argument: // obj : The object to destruct. // // Result: // Return 0 if the object is ready for destruction, any other value // will abort the attempt. // If a string is returned, an error with the string as message will // be issued. // // The gamedriver calls this function whenever an object shall be destructed. // It expects, that this function cleans the inventory of the object, or // the destruct will fail. It is also recommended to clean up all // shadows on obj at this point. // // Furthermore, the function could notify the former inventory objects that // their holder is under destruction (useful to move players out of rooms which // are updated); and it could announce mudwide the destruction(quitting) of // players. // // Another use for this apply is to take care of any other 'cleanup' // work needed to be done, like adjusting weights, light levels, and // such. Alternatively and traditionally this is done by calling an // lfun 'remove()' in the object, which then calls the efun destruct() // after performing all the adjustments. //--------------------------------------------------------------------------- void quota_demon (void) // Handle quotas in times of memory shortage. // // This function is called during the final phase of a garbage collection if // the reserved user area couldn't be reallocated. This function (or a called // demon) has now the opportunity to remove some (still active) objects from // the game. If this does not free enough memory to reallocate the user // reserve, slow_shut_down() will be called to start Armageddon. // // Note: Up to now, the wizlist lacks various informations needed to detect // the memory-hungriest wizards. //--------------------------------------------------------------------------- void receive_udp (string host, string msg, int port) // Handle a received UDP message. // // Arguments: // host: Name of the host the message comes from. // msg : The received message. // port: the port number from which the message was sent. // // This function is called for every message received on the UDP port. //--------------------------------------------------------------------------- void slow_shut_down (int minutes) // Schedule a shutdown for the near future. // // Argument: // minutes: The desired time in minutes till the shutdown: // 6, if just the user reserve has been put into use; // 1, if the (smaller) system or even the master reserve // has been put into use as well. // // The gamedriver calls this function when it runs low on memory. // At this time, it has freed its reserve, but since it won't last long, // the games needs to be shut down. Don't take the 'minutes' as granted // remaining uptime, just deduce the urgency of the shutdown from it. // The delay is to give the players the opportunity to finish quests, // sell their stuff, etc. // It is possible that the driver may reallocate some memory after the // function has been called, and then run again into a low memory situation, // calling this function again. // // For example: this function might load an 'Armageddon' object and tells // it what to do. It is the Armageddon object then which performs // the shutdown. // // Technical: // The memory handling of the gamedriver includes three reserved areas: // user, system and master. All three are there to insure that the game // shuts down gracefully when the memory runs out: the user area to give // the players time to quit normally, the others to enable emergency-logouts // when the user reserve is used up as well. // The areas are allocated at start of the gamedriver, and released when // no more memory could be obtained from the host. In such a case, one // of the remaining areas is freed (so the game can continue a short // while) and a garbagecollection is initiated. // If the garbagecollection recycles enough memory (either true garbage // or by the aid of the quota_demon) to reallocate the areas, all is // fine, else the game is shut down by a call to this function. //--------------------------------------------------------------------------- varargs void notify_shutdown (string crash_reason) // Notify the master about an immediate shutdown. If is 0, // it is a normal shutdown, otherwise it is a crash and // gives a hint at the reason. // // The function has the opportunity to perform any cleanup operation, like // informing the mudwho server that the mud is down. This can not be done // when remove_player() is called because the udp connectivity is already // gone then. // // If the gamedriver shuts down normally , this is the last function called // before the mud shuts down the udp connections and the accepting socket // for new players. // // If the gamedriver crashes, this is the last function called before the // mud attempts to dump core and exit. WARNING: Since the driver is in // an unstable state, this function may not be able to run to completion! // The following crash reasons are defined: // "Fatal Error": an internal sanity check failed. //=========================================================================== // Error Handling // //=========================================================================== //--------------------------------------------------------------------------- void dangling_lfun_closure () // Handle a dangling lfun-closure. // // This is called when the gamedriver executes a closure using a vanished // lfun, with previous_object() showing the originating object. A proper // handling is to raise a runtime error. // // Technical: // Upon replacing programs (see efun replace_program()), any existing // lambda closures of the object are adjusted to the new environment. // If a closure uses a lfun which vanished in the replacement process, // the reference to the lfun is replaced by an alien-lfun closure // referencing this function. The error will then occur when the execution // of the adjusted lambda reaches the point of the lfun reference. // There are two reasons for the delayed handling. First is that the // program replacement and with it the closure adjustment happens at // the end of a backend cycle, outside of any execution thread: noone // would see the error at this time. // Second, smart closures might know/recognize the program replacement // and skip the call to the vanished lfun. { raise_error("dangling lfun closure\n"); } //--------------------------------------------------------------------------- void log_error (string file, string err, int warn) // Announce a compiler-time error or warning. // // Arguments: // file: The name of file containing the error/warning (it needn't be // an object file!). // err : The error/warning message. // warn: non-zero if this is a warning, zero if it is an error. // // Whenever the LPC compiler detects an error or wants to issue a warning, // this function is called. // It should at least log the message in a file, and also announce it // to the active player if it is an wizard. //--------------------------------------------------------------------------- mixed heart_beat_error (object culprit, string err, string prg, string curobj, int line, int caught) // Announce an error in the heart_beat() function. // // Arguments: // culprit: The object which lost the heart_beat. // err : The error message. // prg : The executed program (might be 0). // curobj : The object causing the error (might be 0). // line : The line number where the error occured (might be 0). // caught : 0 if the error is not caught, != 0 if it is caught. // // Result: // Return anything != 0 to restart the heart_beat in culprit. // // This function has to announce an error in the heart_beat() function // of culprit. // At time of call, the heart_beat has been turned off. // A player should at least get a "You have no heartbeat!" message, a more // advanced handling would destruct the offending object and allow the // heartbeat to restart. // // Note that denotes the program actually executed (which might be // inherited one) whereas is just the offending object. //--------------------------------------------------------------------------- void runtime_error (string err, string prg, string curobj, int line , mixed culprit, int caught) // Announce a runtime error. // // Arguments: // err : The error message. // prg : The executed program. // curobj : The object causing the error. // line : The line number where the error occured. // culprit: -1 for runtime errors; the object holding the heart_beat() // function for heartbeat errors. // caught : 0 if the error is not caught, != 0 if it is caught. // // This function has to announce a runtime error to the active user, // resp. handle a runtime error which occured during the execution of // heart_beat() of . // // For a normal runtime error, if the active user is a wizard, it might // give him the full error message together with the source line; if the // user is a is a player, it should issue a decent message ("Your sensitive // mind notices a wrongness in the fabric of space") and could also announce // the error to the wizards online. // // If the error is a heartbeat error, the heartbeat for the offending // has been turned off. The function itself shouldn't do much, since // the lfun heart_beat_error() will be called right after this one. // // Note that denotes the program actually executed (which might be // inherited) whereas is just the offending object for which the // program was executed. // // One common pitfall in the implementation of runtime_error() is that // runtime_error() itself could run out of evaluation ticks, causing a // runtime error itself. The workaround is to use limited() like this: // // static void // handle_runtime_error (string err, string prg, string curobj, int line) // { ... the actual error handler ... } // // static void // call_runtime_error (string err, string prg, string curobj, int line) // { // limited(#'handle_runtime_error, ({ 200000 }), err, prg, curobj, line); // } // // void // runtime_error (string err, string prg, string curobj, int line) // { // limited(#'call_runtime_error, ({ LIMIT_UNLIMITED }) // , err, prg, curobj, line); // } //--------------------------------------------------------------------------- void runtime_warning (string msg, string curobj, string prg, int line , int inside_catch) // Announce a runtime warning. // // Arguments: // err : The warning message. // curobj : The object causing the warning, may be 0. // prg : The executed program, may be 0. // line : The line number where the warning occured. // inside_catch : != 0 if the warning occurs inside a catch(). // // This function is to allow the mudlib to handle runtime warnings, for // example to log them into a database. // // Note that denotes the program actually executed (which might be // inherited) whereas is just the offending object for which the // program was executed. // // The driver imposes a limit of three nested warnings, to prevent endless // recursions. //=========================================================================== // Security and Permissions // // Most of these functions guard critical efuns. A good approach to deal // with them is to redefine the efuns by simul_efuns (which can then avoid // trouble prematurely) and give root objects only the permission to // execute the real efuns. // // See also valid_read() and valid_write(). //=========================================================================== //--------------------------------------------------------------------------- int privilege_violation (string op, mixed who, mixed arg, mixed arg2) // Validate the execution of a privileged operation. // // Arguments: // op : the requestion operation (see below) // who : the object requesting the operation (filename or object pointer) // arg : additional argument, depending on . // arg2 : additional argument, depending on . // // Result: // >0: The caller is allowed for this operation. // 0: The caller was probably misleaded; try to fix the error // else: A real privilege violation; handle it as error. // // Privileged operations are: // attach_erq_demon : Attach the erq demon to object with flag . // bind_lambda : Bind a lambda-closure to object . // call_out_info : Return an array with all call_out informations. // erq : A the request is to be send to the // erq-demon by the object . // enable_telnet : Enable/disable telnet () for object . // execute_command : Execute command string for the object . // input_to : Object issues an 'ignore-bang'-input_to() for // commandgiver ; the exakt flags are . // mysql : Object attempted to execute mySQL efun . // pgsql : Object attempted to execute Postgres efun . // net_connect : Attempt to open a connection to host , // port . // nomask simul_efun : Attempt to get an efun via efun:: when it // is shadowed by a 'nomask'-type simul_efun. // rename_object : The current object renames object // to name . // send_udp : Send UDP-data to host . // get_extra_wizinfo : Get the additional wiz-list info for wizard . // set_extra_wizinfo : Set the additional wiz-list info for wizard . // set_extra_wizinfo_size : Set the size of the additional wizard info // in the wiz-list to . // set_driver_hook : Set hook to . // set_max_commands : Set the max. number of commands interactive // object can issue per second to . // limited : Execute with reduced/changed limits // (as return by query_limits()). // set_limits : Set limits to (as returned by query_limits()). // set_this_object : Set this_object() to . // shadow_add_action : Add an action to function of object // from the shadow which is shadowing . // symbol_variable : Attempt to create symbol of a hidden variable // of object with with index in the // objects variable table. // variable_list : An attempt to return the variable values of object // is made from a different object . // wizlist_info : Return an array with all wiz-list information. // // call_out_info can return the arguments to functions and lambda closures // to be called by call_out(); you should consider that read access to // closures, mappings and pointers means write access and/or other privileges. // wizlist_info() will return an array which holds, among others, the extra // wizlist field. While a toplevel array, if found, will be copied, this does // not apply to nested arrays or to any mappings. You might also have some // sensitive closures there. // send_udp() should be watched as it could be abused. // The xxx_extra_wizinfo operations are necessary for a proper wizlist and // should therefore be restricted to admins. // All other operations are potential sources for direct security breaches - // any use of them should be scrutinized closely. //--------------------------------------------------------------------------- int query_allow_shadow (object victim) // Validate a shadowing. // // Arguments: // previous_object(): the wannabe shadow // victim : the object to be shadowed. // // Result: // Return 0 to disallow the shadowing, any other value to allow it. // Destructing the shadow or the victim is another way of disallowing. // // The function should deny shadowing on all root objects, else it might // query the victim for clearance. //--------------------------------------------------------------------------- int valid_trace (string what, int|string arg) // Check if the player is allowed to use tracing. // // Argument: // what: The actual action (see below). // arg: The argument given to the traceing efun. // // Result: // Return 0 to disallow, any other value to allow it. // // Actions asked for so far are: // "trace": Is the user allowed to use tracing? // is the tracelevel argument given. // "traceprefix": Is the user allowed to set a traceprefix? // is the prefix given. //--------------------------------------------------------------------------- int valid_exec (string name, object ob, object obfrom) // Validate the rebinding of an IP connection by usage of efun exec(). // // Arguments: // name : The name of the _program_ attempting to rebind the connection. // This is not the file_name() of the object, and has no leading // slash. // ob : The object to receive the connection. // obfrom: The object giving the connection away. // // Result: // Return a non-zero number to allow the action, // any other value to disallow it. //--------------------------------------------------------------------------- int valid_query_snoop (object obj) // Validate if the snoopers of an object may be revealed by usage of the // efun query_snoop(). // // Arguments: // previous_object(): the asking object. // obj : the object which snoopers are to be revealed. // // Result: // Return a non-zero number to allow the action, // any other value to disallow it. //--------------------------------------------------------------------------- int valid_snoop (object snoopee, object snooper) // Validate the start/stop of a snoop. // // Arguments: // snoopee: The victim of the snoop. // snooper: The wannabe snooper, or 0 when stopping a snoop. // // Result: // Return a non-zero number to allow the action, // any other value to disallow it. //=========================================================================== // Userids and depending Security // // For each object in the mud exists a string attribute which determines the // objects rights in security-sensitive matters. In compat muds this attribute // is called the "creator" of the object, in !compat muds the object's "userid" // ("uid" for short). // // "Effective Userids" are an extension of this system, to allow the easier // implementation of mudlib security by diffentiating between an objects // theoretical permissions (uid) and its current permissions (euid) (some // experts think that this attempt has failed (Heya Macbeth!)). // // The driver mainly implements the setting/querying of the (e)uids -- it is // task of the mudlib to give out the right (e)uid to the right object, and // to check them where necessary. // // If the driver is set to use 'strict euids', the loading and cloning // of objects requires the initiating object to have a non-zero euid. // // The main use for (e)uids is for determination of file access rights, but // you can of course use the (e)uids for other identification purposes as well. //=========================================================================== //--------------------------------------------------------------------------- string get_bb_uid() // This method is called when efun process_string() is used without a // current object (e.g. from notify_fail method). The current object // will be set to the current command giver, and will receive the euid // returned from this function. // // If strict-euids, this function must exist and return a string. // Otherwise the function is optional and/or may return 0. //--------------------------------------------------------------------------- int valid_seteuid (object obj, string neweuid) // Validate the change of an objects euid by efun seteuid(). // // Arguments: // obj : The object requesting the new euid. // neweuid: The new euid requested. // // Result: // Return 1 to allow the change, any other value to disallow it. //--------------------------------------------------------------------------- mixed valid_read (string path, string euid, string fun, object caller) mixed valid_write (string path, string euid, string fun, object caller) // Validate a reading/writing file operation. // // Arguments: // path : The (possibly partial) filename given to the operation. // euid : the euid of the caller (might be 0). // fun : The name of the operation requested (see below). // caller : The calling object. // // Result: // The full pathname of the file to operate on, or 0 if the action is not // allowed. // You can also return 1 to indicate that the path can be used unchanged. // // The returned pathname must not contain ``..'', a leading / will be stripped // by the interpreter. By default, the returned path must also not contain // space characters; if the driver is instructed to allow them, the // preprocessor macro __FILENAME_SPACES__ is defined. // // These are the central functions establishing the various file access // rights. // // Note that this function is called in compat mode as well! // If you need to be compatible with the old 2.4.5-mudlib, redirect these // calls to the valid_read/valid_write in the player object. // // valid_read() is called for these operations: // copy_file (for the source file) // ed_start (when reading a file) // file_size // get_dir // print_file // read_bytes // read_file // restore_object // tail // // For restore_object(), the passed is the filename as given // in the efun call. // // // valid_write() is called for these operations: // copy_file (for the target file resp. directory name) // ed_start (when writing a file) // garbage_collection (for the log filename) // rename_from (for each the old name of a rename()) // rename_to (for the new name of a rename()) // mkdir // memdump // objdump // opcdump // save_object // remove_file // rmdir // write_bytes // write_file // // For save_object(), the passed is the filename as given // in the efun call. If for this efun a filename ending in ".c" is // returned, the ".c" will be stripped from the filename. //=========================================================================== // ed() Support // //=========================================================================== //--------------------------------------------------------------------------- string make_path_absolute (string str) // Absolutize a relative filename given to the editor. // // Argument: // str : The relative filename (without leading slash). // // Result: // The full pathname of the file to use. // Any non-string result will act as 'bad file name'. //--------------------------------------------------------------------------- int save_ed_setup (object who, int code) // Save individual settings of ed for a wizard. // // Arguments: // who : The wizard using the editor. // code: The encoded options to be saved. // // Result: // Return 0 on failure, any other value for success. // // This function has to save the given integer into a safe place in the // realm of the given wizard, either a file, or in the wizard itself. // // Be aware of possible security breaches: under !compat, a write_file() // should be surrounded by a temporary setting of the masters euid to // that of the wizard. //--------------------------------------------------------------------------- int retrieve_ed_setup (object who) // Retrieve individual settings of ed for a wizard. // // Arguments: // who : The wizard using the editor. // // Result: // The encoded options retrieved (0 if there are none). //--------------------------------------------------------------------------- string get_ed_buffer_save_file_name (string file) // Return a filename for the ed buffer to be saved into. // // Arguments: // this_player(): The wizard using the editor. // file : The name of the file currently in the buffer. // // Result: // The name of the file to save the buffer into, or 0. // // This function is called whenever a wizard is destructed/goes netdeath // while editing. Using this function, his editing is not done in vain. //=========================================================================== // parse_command() Support (!compat, SUPPLY_PARSE_COMMAND defined) // // LPMud has a builtin support for parsing complex commands. // It does this by requestion several types of ids from the objects. // The same queried functions are also in the master to provide decent // defaults, especially for generic ids like 'all the blue ones'. // // Each of the functions has to return an array of strings (with the exception // of parse_command_all_word), each string being one of the ids for that type // of id. // // The whole parsing has a preference for the english language, so the // the code for parsing english constructs is given as well. //=========================================================================== //--------------------------------------------------------------------------- string *parse_command_id_list () // Return generic singular ids. { return ({ "one", "thing" }); } //--------------------------------------------------------------------------- string *parse_command_plural_id_list () // Return generic plural ids. { return ({ "ones", "things", "them" }); } //--------------------------------------------------------------------------- string *parse_command_adjectiv_id_list () // Return generic adjective ids. // If there are none (like here), return some junk which is likely never // typed. { return ({ "iffish" }); } //--------------------------------------------------------------------------- string *parse_command_prepos_list () // Return common prepositions. { return ({ "in", "on", "under", "behind", "beside" }); } //--------------------------------------------------------------------------- string parse_command_all_word() // Return the one(!) 'all' word. { return "all"; } /****************************************************************************/