/* // File : _call.c // Syntax : int cmd_call( string a ); // Purpose : allow wizards to call functions in objects // 92-06-00 : Douglas Reay (aka Pallando @ many muds) wrote a bin based wizard // tool for Ephemeral Dale lpmud (LPC2) // 92-10-00 : Pallando wrote a basic multi-reference tracer for this // 93-01-02 : Pallando changed refs to be stored on player not in daemon // This file is now part of the TMI-II mudlib distribution. // Please retain this header if you use any of this code. // 93-03-19 : Pallando changed refs over to get_objects() // 93-07-17 : Robocoder switched call_other to arrays, ie ({ func, args... }) // 93-08-20 : Grendel allowed admins to call with any euid // 93-08-23 : Pallando changed it to inherit REF_D // 93-10-22 : Mobydick added the ADMIN_ONLY define. */ #include <daemons.h> #include <mudlib.h> #include <logs.h> #include <uid.h> #define NO_USER_CALLS 1 inherit DAEMON; inherit REF_D; #define SYNTAX "Syntax: call [-<uid>] <object>;<function>;<arg>;<arg>\n" #define FUNC_LIST ({ "query_skills", "query_nicknames", "query_aliases" }) #define TAB "\t" static string * do_call( object ob, string func, mixed args ); int cmd_call( string a ) { string str, *exp_a; mixed objs, funcs, args, tmp, ret, rets; object ob; int i, s, fi, fs; if( !a ) { notify_fail( SYNTAX ); return 0; } #ifdef ADMIN_ONLY if (!adminp(geteuid(this_player()))) { write ("Sorry, this command can only be used by admins.\n") ; return 1 ; } #endif #ifdef EVAL_CALL_LOG seteuid(ROOT_UID); if (!adminp(geteuid(this_player()))) log_file(EVAL_CALL_LOG, "************\n" + extract(ctime(time()), 4, 15) + " [" + geteuid(this_player()) + "] call'd: " + a + "\n"); #endif // do this first in case something bombs out below seteuid( geteuid( previous_object() ) ); if(a[0] == '-') { if(a[1] == '-') a = a[2..<1]; else if (geteuid(previous_object()) && adminp(geteuid(previous_object())) && previous_object() == this_player() && this_player() == this_player(1)) { i = strsrch(a, ' '); if(i != -1) { seteuid(a[1..(i-1)]); a = a[(i+1)..<1]; } else { notify_fail("call: seteuid: bad euid\n"); return 0; } } else { notify_fail("call: seteuid: permission denied\n"); return 0; } } exp_a = explode( a, ";" ); s = sizeof( exp_a ); objs = exp_a[0]; if( s > 1 ) funcs = exp_a[1]; else funcs = FUNC_LIST; if( s == 3 ) args = ({ exp_a[2] }); if( s > 3 ) args = exp_a[2..(s-1)]; objs = resolv_ref( objs ); if( objs == "users" ) objs = users(); if( !pointerp( objs ) ) objs = ({ objs }); tmp = ({ }); s = sizeof( objs ); for( i = 0 ; i < s ; i++ ) { if( stringp( objs[i] ) ) ob = get_objects( objs[i],0,1 ); else if( objectp( objs[i] ) ) ob = objs[i]; if( !ob ) write( wrap( "Can't identify " + identify( objs[i] ) + " as an object." ) ); else tmp += ({ ob }); } if( !sizeof( tmp ) ) return 1; objs = tmp; funcs = resolv_ref( funcs ); if( !pointerp( funcs ) ) funcs = ({ funcs }); tmp = ({ }); s = sizeof( funcs ); for( i = 0 ; i < s ; i ++ ) { if( stringp( funcs[i] ) ) tmp += ({ funcs[i] }); else write( wrap( "Can't identify " + identify( funcs[i] )+ " as a string." ) ); } if( !sizeof( tmp ) ) return 1; funcs = tmp; if( pointerp( args ) && ( s = sizeof( args ) ) ) for( i = 0 ; i < s ; i++ ) args[i] = resolv_ref( resolv_str( args[i] ) ); rets = ({ }); s = sizeof( objs ); fs = sizeof( funcs ); for( i = 0 ; i < s ; i++ ) { str = identify( objs[i] ); for( fi = 0 ; fi < fs ; fi++ ) { ret = do_call( objs[i], funcs[fi], args ); if( ret[0] ) rets += ({ ret[0] }); if( fs == 1 ) str = wrap( str + ret[1] ); else str += (fi?"":"\n") + wrap( ret[1] ); } write( str ); } switch( sizeof( rets ) ) { case 0: rets = 0; break; case 1: rets = rets[0]; } set_ref( "default", rets ); return 1; } static string *do_call( object ob, string func, mixed args ) { mixed ret, err; int i, s; string str; object shad; if( !function_exists( func, ob ) ) { for( shad = shadow( ob, 0 ) ; shad ; shad = shadow( shad, 0 ) ) if( function_exists( func, shad ) ) { ob = shad; break; } if( ob != shad ) return ({ 0, "- does not contain " + func + "()" }); } str = "-> " + func; if( pointerp( args ) && ( s = sizeof( args ) ) ) { str += "( "; for( i = 0 ; i < s ; i++ ) { if( i ) str += ", "; str += identify( args[i] ); } str += " )"; } else str += "()"; #ifdef NO_USER_CALLS if (!adminp(getuid(this_player()))) { if (userp(ob) && getuid(ob)!=getuid(this_player())) { return ({ 0, str+" = Illegal operation." }) ; } } #endif if (!s) { err = catch( ret = call_other(ob, func) ); } else { err = catch( ret = call_other(ob, ({ func }) + args) ); } if( err ) return ({ 0, str + TAB + "= ERR(" + identify( err ) + ")" }); return ({ ret, str + TAB + "= " + identify( ret ) }); } int help() { write( SYNTAX + "Effect: Calls the function <function> in object <object>,\n"+ "passing as many arguments <arg> as you give.\n"+ "If no function is specified a dump of the object is given.\n"+ "<object> and <function> can be arrays (eg \"users\")\n"+ "Any of them can be references (qv help refs)\n"+ "" ); return 1; }