|
|
|
|
#include <module_constants.h> |
#include <module.h> |
#include <request_trace.h> |
|
constant __pragma_save_parent__ = 1; |
|
inherit "basic_defvar"; |
mapping(string:array(int)) error_log=([]); |
|
constant is_module = 1; |
|
|
|
constant module_unique = 1; |
|
|
private Configuration _my_configuration; |
private string _module_local_identifier; |
private string _module_identifier = |
lambda() { |
mixed init_info = roxen->bootstrap_info->get(); |
if (arrayp (init_info)) { |
[_my_configuration, _module_local_identifier] = init_info; |
return _my_configuration->name + "/" + _module_local_identifier; |
} |
}(); |
static mapping _api_functions = ([]); |
|
string|array(string) module_creator; |
string module_url; |
RXML.TagSet module_tag_set; |
|
|
|
|
|
|
|
|
void report_fatal( mixed ... args ) { predef::report_fatal( @args ); } |
void report_error( mixed ... args ) { predef::report_error( @args ); } |
void report_notice( mixed ... args ) { predef::report_notice( @args ); } |
void report_debug( mixed ... args ) { predef::report_debug( @args ); } |
|
|
string module_identifier() |
|
|
|
{ |
#if 1 |
return _module_identifier; |
#else |
if (!_module_identifier) { |
string|mapping name = this_object()->register_module()[1]; |
if (mappingp (name)) name = name->standard; |
string cname = sprintf ("%O", my_configuration()); |
if (sscanf (cname, "Configuration(%s", cname) == 1 && |
sizeof (cname) && cname[-1] == ')') |
cname = cname[..sizeof (cname) - 2]; |
_module_identifier = sprintf ("%s,%s", |
name||this_object()->module_name, cname); |
} |
return _module_identifier; |
#endif |
} |
|
string module_local_id() |
|
|
|
|
{ |
return _module_local_identifier; |
} |
|
RoxenModule this_module() |
{ |
return this_object(); |
} |
|
string _sprintf() |
{ |
return sprintf ("RoxenModule(%s)", _module_identifier || "?"); |
} |
|
array register_module() |
{ |
return ({ |
this_object()->module_type, |
this_object()->module_name, |
this_object()->module_doc, |
0, |
module_unique, |
this_object()->module_locked, |
}); |
} |
|
string fix_cvs(string from) |
{ |
from = replace(from, ({ "$", "Id: "," Exp $" }), ({"","",""})); |
sscanf(from, "%*s,v %s", from); |
return replace(from,"/","-"); |
} |
|
int module_dependencies(Configuration configuration, |
array (string) modules, |
int|void now) |
|
|
|
|
|
|
{ |
modules = map (modules, |
lambda (string modname) { |
sscanf ((modname / "/")[-1], "%[^#]", modname); |
return modname; |
}); |
Configuration conf = configuration || my_configuration(); |
if (!conf) |
report_warning ("Configuration not resolved; module(s) %s that %s " |
"depend on weren't added.", String.implode_nicely (modules), |
module_identifier()); |
else |
conf->add_modules( modules, now ); |
return 1; |
} |
|
string file_name_and_stuff() |
{ |
return ("<b>Loaded from:</b> "+(roxen->filename(this_object()))+"<br>"+ |
(this_object()->cvs_version? |
"<b>CVS Version: </b>"+ |
fix_cvs(this_object()->cvs_version)+"\n":"")); |
} |
|
|
Configuration my_configuration() |
|
|
{ |
return _my_configuration; |
} |
|
nomask void set_configuration(Configuration c) |
{ |
if(_my_configuration && _my_configuration != c) |
error("set_configuration() called twice.\n"); |
_my_configuration = c; |
} |
|
void set_module_creator(string|array(string) c) |
|
|
|
|
|
{ |
module_creator = c; |
} |
|
void set_module_url(string to) |
|
|
|
|
{ |
module_url = to; |
} |
|
void free_some_sockets_please(){} |
|
void start(void|int num, void|Configuration conf) {} |
|
string status() {} |
|
string info(Configuration conf) |
{ |
return (this_object()->register_module()[2]); |
} |
|
string sname( ) |
{ |
return my_configuration()->otomod[ this_object() ]; |
} |
|
ModuleInfo my_moduleinfo( ) |
|
{ |
string f = sname(); |
if( f ) return roxen.find_module( (f/"#")[0] ); |
} |
|
void save_me() |
{ |
my_configuration()->save_one( this_object() ); |
my_configuration()->module_changed( my_moduleinfo(), this_object() ); |
} |
|
void save() { save_me(); } |
string comment() { return ""; } |
|
string query_internal_location() |
|
|
{ |
if(!_my_configuration) |
error("Please do not call this function from create()!\n"); |
return _my_configuration->query_internal_location(this_object()); |
} |
|
string query_absolute_internal_location(RequestID id) |
|
{ |
return (id->misc->site_prefix_path || "") + query_internal_location(); |
} |
|
string query_location() |
|
|
|
{ |
string s; |
catch{s = query("location");}; |
return s; |
} |
|
array(string) location_urls() |
|
{ |
string loc = query_location(); |
if (!loc) return ({}); |
if(!_my_configuration) |
error("Please do not call this function from create()!\n"); |
array(string) urls = copy_value(_my_configuration->query("URLs")); |
string hostname; |
if (string world_url = _my_configuration->query ("MyWorldLocation")) |
sscanf (world_url, "%*s://%s%*[:/]", hostname); |
if (!hostname) hostname = gethostname(); |
for (int i = 0; i < sizeof (urls); i++) |
{ |
urls[i] = (urls[i]/"#")[0]; |
if (sizeof (urls[i]/"*") == 2) |
urls[i] = replace(urls[i], "*", hostname); |
} |
return map (urls, `+, loc[1..]); |
} |
|
|
string query_provides() { return 0; } |
|
|
function(RequestID:int|mapping) query_seclevels() |
{ |
if(catch(query("_seclevels")) || (query("_seclevels") == 0)) |
return 0; |
return roxen.compile_security_pattern(query("_seclevels"),this_object()); |
} |
|
Stat stat_file(string f, RequestID id){} |
array(string) find_dir(string f, RequestID id){} |
mapping(string:Stat) find_dir_stat(string f, RequestID id) |
{ |
TRACE_ENTER("find_dir_stat(): \""+f+"\"", 0); |
|
array(string) files = find_dir(f, id); |
mapping(string:Stat) res = ([]); |
|
foreach(files || ({}), string fname) { |
TRACE_ENTER("stat()'ing "+ f + "/" + fname, 0); |
Stat st = stat_file(replace(f + "/" + fname, "//", "/"), id); |
if (st) { |
res[fname] = st; |
TRACE_LEAVE("OK"); |
} else { |
TRACE_LEAVE("No stat info"); |
} |
} |
|
TRACE_LEAVE(""); |
return(res); |
} |
|
string real_file(string f, RequestID id){} |
|
void add_api_function( string name, function f, void|array(string) types) |
{ |
_api_functions[name] = ({ f, types }); |
} |
|
mapping api_functions() |
{ |
return _api_functions; |
} |
|
#if ROXEN_COMPAT <= 1.4 |
mapping(string:function) query_tag_callers() |
|
{ |
mapping(string:function) m = ([]); |
foreach(glob("tag_*", indices( this_object())), string q) |
if(functionp( this_object()[q] )) |
m[replace(q[4..], "_", "-")] = this_object()[q]; |
return m; |
} |
|
mapping(string:function) query_container_callers() |
|
{ |
mapping(string:function) m = ([]); |
foreach(glob("container_*", indices( this_object())), string q) |
if(functionp( this_object()[q] )) |
m[replace(q[10..], "_", "-")] = this_object()[q]; |
return m; |
} |
#endif |
|
mapping(string:array(int|function)) query_simpletag_callers() |
{ |
mapping(string:array(int|function)) m = ([]); |
foreach(glob("simpletag_*", indices(this_object())), string q) |
if(functionp(this_object()[q])) |
m[replace(q[10..],"_","-")] = |
({ intp (this_object()[q + "_flags"]) && this_object()[q + "_flags"], |
this_object()[q] }); |
return m; |
} |
|
mapping(string:array(int|function)) query_simple_pi_tag_callers() |
{ |
mapping(string:array(int|function)) m = ([]); |
foreach (glob ("simple_pi_tag_*", indices (this_object())), string q) |
if (functionp (this_object()[q])) |
m[replace (q[sizeof ("simple_pi_tag_")..], "_", "-")] = |
({(intp (this_object()[q + "_flags"]) && this_object()[q + "_flags"]) | |
RXML.FLAG_PROC_INSTR, this_object()[q]}); |
return m; |
} |
|
RXML.TagSet query_tag_set() |
{ |
if (!module_tag_set) { |
array(function|program|object) tags = |
filter (rows (this_object(), |
glob ("Tag*", indices (this_object()))), |
functionp); |
for (int i = 0; i < sizeof (tags); i++) |
if (programp (tags[i])) |
if (!tags[i]->is_RXML_Tag) tags[i] = 0; |
else tags[i] = tags[i](); |
else { |
tags[i] = tags[i](); |
|
if (!tags[i]->is_RXML_Tag) tags[i] = 0; |
} |
tags -= ({0}); |
module_tag_set = |
(this_object()->ModuleTagSet || RXML.TagSet) (this_object(), "", tags); |
} |
return module_tag_set; |
} |
|
mixed get_value_from_file(string path, string index, void|string pre) |
{ |
Stdio.File file=Stdio.File(); |
if(!file->open(path,"r")) return 0; |
if(index[sizeof(index)-2..sizeof(index)-1]=="()") { |
return compile_string((pre||"")+file->read())[index[..sizeof(index)-3]](); |
} |
return compile_string((pre||"")+file->read())[index]; |
} |
|
static private mapping __my_tables = ([]); |
|
array(mapping(string:mixed)) sql_query( string query, mixed ... args ) |
|
|
|
|
|
|
|
|
{ |
return get_my_sql()->query( replace( query, __my_tables ), @args ); |
} |
|
object sql_big_query( string query, mixed ... args ) |
|
|
{ |
return get_my_sql()->big_query( replace( query, __my_tables ), @args ); |
} |
|
array(mapping(string:mixed)) sql_query_ro( string query, mixed ... args ) |
|
|
|
|
|
|
|
|
{ |
return get_my_sql(1)->query( replace( query, __my_tables ), @args ); |
} |
|
object sql_big_query_ro( string query, mixed ... args ) |
|
|
{ |
return get_my_sql(1)->big_query( replace( query, __my_tables ), @args ); |
} |
|
static int create_sql_tables( mapping(string:array(string)) defenitions, |
string|void comment, |
int|void no_unique_names ) |
|
|
{ |
int ddc; |
if( !no_unique_names ) |
foreach( indices( defenitions ), string t ) |
ddc+=get_my_table( t, defenitions[t], comment, 1 ); |
else |
{ |
Sql.Sql sql = get_my_sql(); |
foreach( indices( defenitions ), string t ) |
{ |
if( !catch { |
sql->query("CREATE TABLE "+t+" ("+defenitions[t]*","+")" ); |
} ) |
ddc++; |
DBManager.is_module_table( this_object(), my_db, t, comment ); |
} |
} |
return ddc; |
} |
|
static string sql_table_exists( string name ) |
|
{ |
if(strlen(name)) |
name = "_"+name; |
|
string res = hash(_my_configuration->name)->digits(36) |
+ "_" + replace(sname(),"#","_") + name; |
|
return catch(get_my_sql()->query( "SELECT * FROM "+res+" LIMIT 1" ))?0:res; |
} |
|
|
static string|int get_my_table( string|array(string) name, |
void|array(string)|string defenition, |
string|void comment, |
int|void flag ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
string oname; |
int ddc; |
if( !defenition ) |
{ |
defenition = name; |
oname = name = ""; |
} |
else if(strlen(name)) |
name = "_"+(oname = name); |
|
Sql.Sql sql = get_my_sql(); |
|
string res = hash(_my_configuration->name)->digits(36) |
+ "_" + replace(sname(),"#","_") + name; |
|
if( !sql ) |
{ |
report_error("Failed to get SQL handle, permission denied for "+my_db+"\n"); |
return 0; |
} |
if( arrayp( defenition ) ) |
defenition *= ", "; |
|
if( catch(sql->query( "SELECT * FROM "+res+" LIMIT 1" )) ) |
{ |
ddc++; |
mixed error = |
catch |
{ |
get_my_sql()->query( "CREATE TABLE "+res+" ("+defenition+")" ); |
DBManager.is_module_table( this_object(), my_db, res, |
oname+"\0"+comment ); |
}; |
if( error ) |
{ |
if( strlen( name ) ) |
name = " "+name; |
report_error( "Failed to create table"+name+": "+ |
describe_error( error ) ); |
return 0; |
} |
if( flag ) |
{ |
__my_tables[ "&"+oname+";" ] = res; |
return ddc; |
} |
return __my_tables[ "&"+oname+";" ] = res; |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
if( flag ) |
{ |
__my_tables[ "&"+oname+";" ] = res; |
return ddc; |
} |
return __my_tables[ "&"+oname+";" ] = res; |
} |
|
static string my_db = "local"; |
|
static void set_my_db( string to ) |
|
|
|
{ |
my_db = to; |
} |
|
Sql.Sql get_my_sql( int|void read_only ) |
|
|
|
|
|
{ |
return DBManager.cached_get( my_db, _my_configuration, read_only ); |
} |
|
|