mud/lib/secure/daemon/function.c
2020-09-06 05:43:07 -07:00

209 lines
6.1 KiB
C

#include <lib.h>
#include <save.h>
#include <daemons.h>
#include <runtime_config.h>
inherit LIB_DAEMON;
static string globaltmp;
static string *files = ({});
static string SaveFuns = save_file(SAVE_FUNCTIONS);
static int seeking = 0;
static int count = 0;
mapping FileSize = ([]);
mapping FunctionCache = ([]);
mixed *Functions = ({});
mapping LCFunctions = ([]);
mapping TmpMap = ([]);
static private void validate() {
if(!this_player()) return 0;
if( !(master()->valid_apply(({ "ASSIST" }))) )
error("Illegal attempt access FUNCTIONS_D: "+get_stack()+" "+identify(previous_object(-1)));
if(query_os_type() == "windows"){
error("The functions daemon has been disabled for your mud "+
"because it is running on windows. Intensive file operations "+
"in windows are not yet supported on Dead Souls.");
}
}
void heart_beat(){
if(seeking){
foreach(mixed arr in call_out_info()){
if(arr[0] == this_object()){
return ;
}
}
SaveObject(SaveFuns);
seeking = 0;
}
count++;
if(count > 700){
SaveObject(SaveFuns);
count = 0;
}
}
mixed SendFiles(string *arr){
if(query_os_type() == "windows" || !(MASTER_D->GetPerfOK())){
return 0;
}
validate();
foreach(string sub in arr){
reset_eval_cost();
load_object("/secure/cmds/creators/showfuns")->cmd(sub);
}
return 1;
}
mixed SendFiles2(string *arr){
string prefix, file, tmpfile, ret = "";
object ob;
mixed deffed = ({});
int err;
foreach(string element in arr){
reset_eval_cost();
if(!strsrch(element, "/lib/")){
prefix = path_prefix(element);
file = replace_string(element, prefix, "");
tmpfile = prefix+"/"+file+alpha_crypt(5)+time()+".c";
write_file(tmpfile, "#pragma save_types\n", 1);
write_file(tmpfile, read_file(element));
err = catch( ob = load_object(tmpfile) );
if(err || !ob){
rm(tmpfile);
tmpfile = 0;
err = catch( ob = load_object(element) );
}
if(err || !ob) continue;
filter(functions(ob, 1), (: TmpMap[$1[0]] = $1[1..] :) );
foreach(string fun in functions(ob)){
if(function_exists(fun, ob) == base_name(ob)){
deffed += ({ fun });
}
}
foreach(string mos in deffed){
ret += TmpMap[mos][1]+" "+mos+"("+
implode(TmpMap[mos][2..], ", ")+")\n";
}
}
}
return ret;
}
mixed ReadFuns(string str){
int interval = 0;
string *subfiles = ({});
if(query_os_type() == "windows" || !(MASTER_D->GetPerfOK())){
return 0;
}
validate();
seeking = 1;
if(!str || !sizeof(str)) str = "/lib";
files = FILE_D->GetFiles();
globaltmp = str;
files = filter(files, (: (!strsrch($1, globaltmp) && last($1,2) == ".c" ) :) );
files = filter(files, (: (!sizeof(FunctionCache[$1]) ||
((sizeof(stat($1)) > 1) ? stat($1)[0] : FileSize[$1])
!= FileSize[$1]) :) );
while(sizeof(files) > 0){
reset_eval_cost();
interval++;
subfiles = ({ files[0] }) ;
files -= subfiles;
call_out( (: SendFiles, subfiles :), interval);
}
return 1;
}
static void create() {
daemon::create();
if(!file_exists(SaveFuns) && file_exists(old_savename(SaveFuns))){
cp(old_savename(SaveFuns), SaveFuns);
}
RestoreObject(SaveFuns);
if(query_os_type() == "windows" || !(MASTER_D->GetPerfOK())){
return;
}
validate();
TmpMap = ([]);
call_out((: ReadFuns,"/lib/" :), 1);
set_heart_beat(1);
}
varargs int ReceiveFunctionData(string file, string funs, int fsize, mixed fs){
FunctionCache[file] = funs;
FileSize[file] = fsize;
if(sizeof(fs) && arrayp(fs)){
if(!Functions) Functions = ({});
if(!LCFunctions) LCFunctions = ([]);
if((sizeof(Functions) + sizeof(fs)) < 64000){
Functions += fs;
Functions = distinct_array(Functions);
foreach(string fun in fs){
string lname = lower_case(fun);
if(!LCFunctions[lname]) LCFunctions[lname] = ({});
LCFunctions[lname] += ({ fun });
LCFunctions[lname] = distinct_array(LCFunctions[lname]);
}
}
}
return fsize;
}
varargs mixed GetFunctions(string str){
if(!str) return copy(Functions);
if(this_player() && (!FileSize[str] || stat(str)[0] != FileSize[str])) return 0;
return FunctionCache[str];
}
varargs mixed GetLCFunctions(string str, int subs){
string *ret = ({}), *l_funs, *e_funs, *se_funs;
if(!LCFunctions) LCFunctions = ([]);
if(!str) return copy(LCFunctions);
str = lower_case(str);
if(!subs){
return LCFunctions[str];
}
l_funs = regexp(keys(LCFunctions), str);
foreach(mixed foo in l_funs){
if(sizeof(LCFunctions[foo]))
ret += LCFunctions[foo];
}
ret = distinct_array(ret);
e_funs = regexp(efuns(), str);
se_funs = regexp(sefuns(), str);
if(sizeof(e_funs) + sizeof(ret) < 64000) ret += e_funs;
if(sizeof(se_funs) + sizeof(ret) < 64000) ret += se_funs;
ret = sort_array(distinct_array(ret), 1);
return ret;
}
int eventDestruct(){
SaveObject(SaveFuns);
return ::eventDestruct();
}
varargs mixed GetInstances(string str, string where){
string cooked_list = "";
if(!where || ! sizeof(where)) where = "/lib/";
if(!sizeof(FunctionCache)) return 0;
foreach(string key, string val in FunctionCache){
string funex;
object cle;
if(grepp(val, str) && !strsrch(key,where)){
if(!sizeof(key) || !unguarded( (: file_exists($(key)) :)) ||
catch(cle = load_object(key)) || !cle){
continue;
}
funex = function_exists(str, cle,1);
if(funex && !grepp(cooked_list,funex+"\n")){
cooked_list += funex+"\n";
}
}
}
return cooked_list;
}