1b2b752000-01-07Martin Stjernholm /* $Id: module.pike,v 1.63 2000/01/07 02:32:41 mast Exp $ */
b1fca01996-11-12Per Hedbor #include <module.h>
c5e0961999-10-04Per Hedbor #include <request_trace.h>
b275871998-05-23Henrik Grubbström (Grubba) 
b1fca01996-11-12Per Hedbor mapping (string:mixed *) variables=([]);
7fb7f51999-11-29Per Hedbor RoxenModule this = this_object();
9d9b9b1999-11-17Per Hedbor mapping(string:array(int)) error_log=([]);
c5e0961999-10-04Per Hedbor 
9d9b9b1999-11-17Per Hedbor constant is_module = 1;
c5e0961999-10-04Per Hedbor constant module_type = MODULE_PARSER; constant module_name = "Unnamed module"; constant module_doc = "Undocumented"; constant module_unique = 1;
b9ec252000-01-05Martin Stjernholm private string _module_identifier; string module_identifier() { if (!_module_identifier) { string|mapping name = register_module()[1]; if (mappingp (name)) name = name->standard; _module_identifier = sprintf ("%s,%O", name || module_name, my_configuration()); } return _module_identifier; }
b6fb051999-11-02Per Hedbor string _sprintf() {
b9ec252000-01-05Martin Stjernholm  return "RoxenModule(" + module_identifier() + ")";
b6fb051999-11-02Per Hedbor }
c5e0961999-10-04Per Hedbor array register_module() { return ({ module_type, module_name, module_doc, 0, module_unique, }); }
2a2a5b1996-12-01Per Hedbor string fix_cvs(string from) {
fd0b6f1996-12-02Per Hedbor  from = replace(from, ({ "$", "Id: "," Exp $" }), ({"","",""}));
2a2a5b1996-12-01Per Hedbor  sscanf(from, "%*s,v %s", from);
00730e1999-11-18Per Hedbor  return replace(from,"/","-");
2a2a5b1996-12-01Per Hedbor }
7fb7f51999-11-29Per Hedbor int module_dependencies(Configuration configuration,
f5a2741999-10-18Per Hedbor  array (string) modules, int|void now)
edb5061997-08-25Peter Bortas {
f5a2741999-10-18Per Hedbor  if(configuration) configuration->add_modules( modules, now );
0fce591999-06-09Martin Stjernholm  mixed err; if (err = catch (_do_call_outs())) report_error ("Error doing call outs:\n" + describe_backtrace (err));
edb5061997-08-25Peter Bortas  return 1; }
2a2a5b1996-12-01Per Hedbor string file_name_and_stuff() { return ("<b>Loaded from:</b> "+(roxen->filename(this))+"<br>"+
00730e1999-11-18Per Hedbor  (this->cvs_version? "<b>CVS Version: </b>"+ fix_cvs(this->cvs_version)+"\n":""));
2a2a5b1996-12-01Per Hedbor }
9f2a971999-11-29Per Hedbor static private Configuration _my_configuration;
5839c31999-01-22Marcus Comstedt 
9f2a971999-11-29Per Hedbor Configuration my_configuration()
b1fca01996-11-12Per Hedbor {
5839c31999-01-22Marcus Comstedt  if(_my_configuration) return _my_configuration;
7fb7f51999-11-29Per Hedbor  Configuration conf;
b1fca01996-11-12Per Hedbor  foreach(roxen->configurations, conf) if(conf->otomod[this])
33266d1999-05-24Per Hedbor  return _my_configuration = conf;
b1fca01996-11-12Per Hedbor  return 0; }
7fb7f51999-11-29Per Hedbor nomask void set_configuration(Configuration c)
5839c31999-01-22Marcus Comstedt { if(_my_configuration && _my_configuration != c) error("set_configuration() called twice.\n"); _my_configuration = c; }
b1fca01996-11-12Per Hedbor string module_creator; string module_url; void set_module_creator(string c) { module_creator = c; } void set_module_url(string to) { module_url = to; } int killvar(string var) {
2a2a5b1996-12-01Per Hedbor  if(!variables[var]) error("Killing undefined variable.\n");
b1fca01996-11-12Per Hedbor  m_delete(variables, var); return 1; } void free_some_sockets_please(){}
7fb7f51999-11-29Per Hedbor void start(void|int num, void|Configuration conf) {}
b1fca01996-11-12Per Hedbor string status() {}
c5e0961999-10-04Per Hedbor 
7fb7f51999-11-29Per Hedbor string info(Configuration conf)
b1fca01996-11-12Per Hedbor {
7fb7f51999-11-29Per Hedbor  return (this->register_module()[2]);
b1fca01996-11-12Per Hedbor }
9d9b9b1999-11-17Per Hedbor constant ConfigurableWrapper = roxen.ConfigurableWrapper;
efc8111999-09-05Per Hedbor constant reg_s_loc = Locale.Roxen.standard.register_module_doc;
b1fca01996-11-12Per Hedbor // Define a variable, with more than a little error checking...
7fb7f51999-11-29Per Hedbor void defvar(string var, mixed value, string name, int type, string|void doc_str, mixed|void misc,
c856841998-01-21Henrik Grubbström (Grubba)  int|function|void not_in_config)
b1fca01996-11-12Per Hedbor {
273b3f1999-12-28Martin Nilsson #ifdef MODULE_DEBUG
b1fca01996-11-12Per Hedbor  if(!strlen(var))
273b3f1999-12-28Martin Nilsson  report_debug("No name for variable!\n");
5e4ede1996-11-12Per Hedbor // if(var[0]=='_' && previous_object() != roxen)
273b3f1999-12-28Martin Nilsson // report_debug("Variable names beginning with '_' are reserved for"
5e4ede1996-11-12Per Hedbor // " internal usage.\n");
b1fca01996-11-12Per Hedbor  if (!stringp(name))
273b3f1999-12-28Martin Nilsson  report_debug("The variable "+var+"has no name.\n");
efc8111999-09-05Per Hedbor 
f6d62d1997-03-26Per Hedbor  if((search(name, "\"") != -1))
273b3f1999-12-28Martin Nilsson  report_debug("Please do not use \" in variable names");
b1fca01996-11-12Per Hedbor  if (!stringp(doc_str)) doc_str = "No documentation";
df6cd11998-10-13Per Hedbor 
b1fca01996-11-12Per Hedbor  switch (type & VAR_TYPE_MASK) {
be377f1997-06-12Henrik Grubbström (Grubba)  case TYPE_NODE: if(!arrayp(value))
273b3f1999-12-28Martin Nilsson  report_debug("TYPE_NODE variables should contain a list of variables "
be377f1997-06-12Henrik Grubbström (Grubba)  "to use as subnodes.\n"); break; case TYPE_CUSTOM: if(!misc && arrayp(misc) && (sizeof(misc)>=3) && functionp(misc[0]) && functionp(misc[1]) && functionp(misc[2]))
273b3f1999-12-28Martin Nilsson  report_debug("When defining a TYPE_CUSTOM variable, the MISC " "field must be an array of functionpointers: \n" "({describe,describe_form,set_from_form})\n");
be377f1997-06-12Henrik Grubbström (Grubba)  break; case TYPE_TEXT_FIELD: case TYPE_FILE: case TYPE_STRING: case TYPE_LOCATION: case TYPE_PASSWORD: if(value && !stringp(value)) {
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal value (%t:%O) " "to string type variable.\n", roxen->filename(this), value, value);
be377f1997-06-12Henrik Grubbström (Grubba)  } break;
b1fca01996-11-12Per Hedbor 
be377f1997-06-12Henrik Grubbström (Grubba)  case TYPE_FLOAT: if(!floatp(value))
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal value (%t:%O) " "(not float) to floating point " "decimal number variable.\n", roxen->filename(this), value, value);
be377f1997-06-12Henrik Grubbström (Grubba)  break; case TYPE_INT: if(!intp(value))
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal value (%t:%O) " "(not int) to integer number variable.\n", roxen->filename(this), value, value);
be377f1997-06-12Henrik Grubbström (Grubba)  break; case TYPE_MODULE_LIST: value = ({}); break;
b1fca01996-11-12Per Hedbor 
be377f1997-06-12Henrik Grubbström (Grubba)  case TYPE_MODULE: /* No default possible */ value = 0; break; case TYPE_DIR_LIST: int i; if(!arrayp(value)) {
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nIllegal type %t to TYPE_DIR_LIST, " "must be array.\n", roxen->filename(this), value);
be377f1997-06-12Henrik Grubbström (Grubba)  value = ({ "./" }); } else { for(i=0; i<sizeof(value); i++) { if(strlen(value[i])) { if(value[i][-1] != '/') value[i] += "/";
0f8c871997-06-01Henrik Grubbström (Grubba)  } else { value[i]="./"; }
be377f1997-06-12Henrik Grubbström (Grubba)  } } break; case TYPE_DIR: if(value && !stringp(value))
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal value (%t:%O) (not string) " "to directory variable.\n", roxen->filename(this), value, value);
b1fca01996-11-12Per Hedbor 
be377f1997-06-12Henrik Grubbström (Grubba)  if(value && strlen(value) && ((string)value)[-1] != '/') value+="/"; break; case TYPE_INT_LIST: case TYPE_STRING_LIST: if(!misc && value && !arrayp(value)) {
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal misc (%t:%O) (not array) " "to multiple choice variable.\n", roxen->filename(this), value, value);
be377f1997-06-12Henrik Grubbström (Grubba)  } else { if(misc && !arrayp(misc)) {
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal misc (%t:%O) (not array) " "to multiple choice variable.\n", roxen->filename(this), misc, misc);
be377f1997-06-12Henrik Grubbström (Grubba)  }
afd9501998-07-24Martin Stjernholm  if(misc && value && search(misc, value)==-1) {
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing value (%t:%O) not present " "in the misc array.\n", roxen->filename(this), value, value);
be377f1997-06-12Henrik Grubbström (Grubba)  } }
b1fca01996-11-12Per Hedbor  break;
0f8c871997-06-01Henrik Grubbström (Grubba)  case TYPE_FLAG:
b1fca01996-11-12Per Hedbor  value=!!value; break;
0f8c871997-06-01Henrik Grubbström (Grubba)  case TYPE_ERROR:
b1fca01996-11-12Per Hedbor  break;
0f8c871997-06-01Henrik Grubbström (Grubba)  case TYPE_COLOR:
b1fca01996-11-12Per Hedbor  if (!intp(value))
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nPassing illegal value (%t:%O) (not int) " "to color variable.\n", roxen->filename(this), value, value);
b1fca01996-11-12Per Hedbor  break;
be377f1997-06-12Henrik Grubbström (Grubba)  case TYPE_FILE_LIST: case TYPE_PORTS: case TYPE_FONT: // FIXME: Add checks for these. break;
0f8c871997-06-01Henrik Grubbström (Grubba)  default:
273b3f1999-12-28Martin Nilsson  report_debug("%s:\nIllegal type (%s) in defvar.\n", roxen->filename(this), type);
0f8c871997-06-01Henrik Grubbström (Grubba)  break;
b1fca01996-11-12Per Hedbor  }
efc8111999-09-05Per Hedbor #endif // Locale stuff. reg_s_loc( this_object(), var, name, doc_str );
df6cd11998-10-13Per Hedbor 
b1fca01996-11-12Per Hedbor  variables[var]=allocate( VAR_SIZE ); variables[var][ VAR_VALUE ]=value; variables[var][ VAR_TYPE ]=type&VAR_TYPE_MASK; variables[var][ VAR_DOC_STR ]=doc_str; variables[var][ VAR_NAME ]=name;
e416431998-07-07Henrik Grubbström (Grubba)  type &= ~VAR_TYPE_MASK; // Probably not needed, but... type &= (VAR_EXPERT | VAR_MORE); if (functionp(not_in_config)) { if (type) { variables[var][ VAR_CONFIGURABLE ] = ConfigurableWrapper(type, not_in_config)->check; } else { variables[var][ VAR_CONFIGURABLE ] = not_in_config; } } else if (type) { variables[var][ VAR_CONFIGURABLE ] = type; } else if(intp(not_in_config)) { variables[var][ VAR_CONFIGURABLE ] = !not_in_config; }
b1fca01996-11-12Per Hedbor  variables[var][ VAR_MISC ]=misc; variables[var][ VAR_SHORTNAME ]= var; }
efc8111999-09-05Per Hedbor static mapping locs = ([]);
df6cd11998-10-13Per Hedbor void deflocaledoc( string locale, string variable,
b796b51998-11-18Per Hedbor  string name, string doc, mapping|void translate )
df6cd11998-10-13Per Hedbor {
efc8111999-09-05Per Hedbor  if(!locs[locale] ) locs[locale] = Locale.Roxen[locale]->register_module_doc; if(!locs[locale])
df6cd11998-10-13Per Hedbor  report_debug("Invalid locale: "+locale+". Ignoring.\n"); else
efc8111999-09-05Per Hedbor  locs[locale]( this_object(), variable, name, doc, translate );
df6cd11998-10-13Per Hedbor }
b1fca01996-11-12Per Hedbor 
2c13a81999-11-10Per Hedbor void save_me()
e7e6031999-11-05Per Hedbor { my_configuration()->save_one( this_object() ); }
2c13a81999-11-10Per Hedbor void save() { save_me(); }
4cf1151999-04-24Henrik Grubbström (Grubba) // Convenience function, define an invisible variable, this variable // will be saved, but it won't be visible in the configuration interface.
0f8c871997-06-01Henrik Grubbström (Grubba) void definvisvar(string name, int value, int type, array|void misc)
b1fca01996-11-12Per Hedbor {
0f8c871997-06-01Henrik Grubbström (Grubba)  defvar(name, value, "", type, "", misc, 1);
b1fca01996-11-12Per Hedbor } string check_variable( string s, mixed value ) { // Check if `value' is O.K. to store in the variable `s'. If so, // return 0, otherwise return a string, describing the error. return 0; }
c856841998-01-21Henrik Grubbström (Grubba) mixed query(string|void var, int|void ok)
b1fca01996-11-12Per Hedbor {
c856841998-01-21Henrik Grubbström (Grubba)  if(var) {
b1fca01996-11-12Per Hedbor  if(variables[var]) return variables[var][VAR_VALUE];
c6fa431998-11-22Per Hedbor  else if(!ok && var[0] != '_')
b1fca01996-11-12Per Hedbor  error("Querying undefined variable.\n");
c6fa431998-11-22Per Hedbor  return 0;
c856841998-01-21Henrik Grubbström (Grubba)  }
b1fca01996-11-12Per Hedbor  return variables; } void set(string var, mixed value) { if(!variables[var]) error( "Setting undefined variable.\n" );
7fb7f51999-11-29Per Hedbor  variables[var][VAR_VALUE]=value;
b1fca01996-11-12Per Hedbor } int setvars( mapping (string:mixed) vars ) { string v; int err; foreach( indices( vars ), v ) if(variables[v]) set( v, vars[v] ); return !err; } string comment() { return ""; }
5839c31999-01-22Marcus Comstedt 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()); }
b7c45e1997-01-27Per Hedbor /* Per default, return the value of the module variable 'location' */ string query_location() { string s; catch{s = query("location");}; return s; }
ae32d01998-03-23David Hedbor /* By default, provide nothing. */ string query_provides() { return 0; }
b7c45e1997-01-27Per Hedbor 
b1fca01996-11-12Per Hedbor /* * Parse and return a parsed version of the security levels for this module * */
17d1731997-08-13Henrik Grubbström (Grubba) class IP_with_mask { int net; int mask; static private int ip_to_int(string ip) { int res;
eac26d1997-09-27Henrik Grubbström (Grubba)  foreach(((ip/".") + ({ "0", "0", "0" }))[..3], string num) {
17d1731997-08-13Henrik Grubbström (Grubba)  res = res*256 + (int)num; } return(res); }
4117501997-08-13Henrik Grubbström (Grubba)  void create(string _ip, string|int _mask)
17d1731997-08-13Henrik Grubbström (Grubba)  { net = ip_to_int(_ip);
4117501997-08-13Henrik Grubbström (Grubba)  if (intp(_mask)) { if (_mask > 32) { report_error(sprintf("Bad netmask: %s/%d\n" "Using %s/32\n", _ip, _mask, _ip)); _mask = 32; } mask = ~0<<(32-_mask); } else { mask = ip_to_int(_mask); }
17d1731997-08-13Henrik Grubbström (Grubba)  if (net & ~mask) {
4117501997-08-13Henrik Grubbström (Grubba)  report_error(sprintf("Bad netmask: %s for network %s\n" "Ignoring node-specific bits\n", _ip, _mask)); net &= mask;
17d1731997-08-13Henrik Grubbström (Grubba)  } } int `()(string ip) { return((ip_to_int(ip) & mask) == net); } };
b7c45e1997-01-27Per Hedbor 
b1fca01996-11-12Per Hedbor array query_seclevels() { array patterns=({ });
de493f1997-04-28Henrik Grubbström (Grubba)  if(catch(query("_seclevels"))) {
b1fca01996-11-12Per Hedbor  return patterns;
de493f1997-04-28Henrik Grubbström (Grubba)  }
b1fca01996-11-12Per Hedbor 
4117501997-08-13Henrik Grubbström (Grubba)  foreach(replace(query("_seclevels"), ({" ","\t","\\\n"}), ({"","",""}))/"\n", string sl) {
b1fca01996-11-12Per Hedbor  if(!strlen(sl) || sl[0]=='#') continue;
de493f1997-04-28Henrik Grubbström (Grubba) 
b1fca01996-11-12Per Hedbor  string type, value; if(sscanf(sl, "%s=%s", type, value)==2) {
de493f1997-04-28Henrik Grubbström (Grubba)  switch(lower_case(type))
b1fca01996-11-12Per Hedbor  { case "allowip":
4117501997-08-13Henrik Grubbström (Grubba)  array(string|int) arr; if (sizeof(arr = (value/"/")) == 2) { // IP/bits arr[1] = (int)arr[1]; patterns += ({ ({ MOD_ALLOW, IP_with_mask(@arr) }) }); } else if ((sizeof(arr = (value/":")) == 2) ||
8919711998-02-06Gerald Schupfner  (sizeof(arr = (value/",")) > 1)) {
4117501997-08-13Henrik Grubbström (Grubba)  // IP:mask or IP,mask patterns += ({ ({ MOD_ALLOW, IP_with_mask(@arr) }) }); } else { // Pattern
17d1731997-08-13Henrik Grubbström (Grubba)  value = replace(value, ({ "?", ".", "*" }), ({ ".", "\\.", ".*" })); patterns += ({ ({ MOD_ALLOW, Regexp(value)->match, }) }); }
b1fca01996-11-12Per Hedbor  break;
9579781998-06-29Henrik Grubbström (Grubba)  case "acceptip": // Short-circuit version of allow ip. array(string|int) arr; if (sizeof(arr = (value/"/")) == 2) { // IP/bits arr[1] = (int)arr[1]; patterns += ({ ({ MOD_ACCEPT, IP_with_mask(@arr) }) }); } else if ((sizeof(arr = (value/":")) == 2) || (sizeof(arr = (value/",")) > 1)) { // IP:mask or IP,mask patterns += ({ ({ MOD_ACCEPT, IP_with_mask(@arr) }) }); } else { // Pattern value = replace(value, ({ "?", ".", "*" }), ({ ".", "\\.", ".*" })); patterns += ({ ({ MOD_ACCEPT, Regexp(value)->match, }) }); } break;
b1fca01996-11-12Per Hedbor  case "denyip":
4117501997-08-13Henrik Grubbström (Grubba)  array(string|int) arr; if (sizeof(arr = (value/"/")) == 2) { // IP/bits arr[1] = (int)arr[1]; patterns += ({ ({ MOD_DENY, IP_with_mask(@arr) }) }); } else if ((sizeof(arr = (value/":")) == 2) ||
8919711998-02-06Gerald Schupfner  (sizeof(arr = (value/",")) > 1)) {
4117501997-08-13Henrik Grubbström (Grubba)  // IP:mask or IP,mask patterns += ({ ({ MOD_DENY, IP_with_mask(@arr) }) }); } else { // Pattern
17d1731997-08-13Henrik Grubbström (Grubba)  value = replace(value, ({ "?", ".", "*" }), ({ ".", "\\.", ".*" })); patterns += ({ ({ MOD_DENY, Regexp(value)->match, }) }); }
b1fca01996-11-12Per Hedbor  break;
f6d62d1997-03-26Per Hedbor  case "allowuser":
17d1731997-08-13Henrik Grubbström (Grubba)  value = replace(value, ({ "?", ".", "*" }), ({ ".", "\\.", ".*" }));
f6d62d1997-03-26Per Hedbor  array(string) users = (value/"," - ({""})); int i; for(i=0; i < sizeof(users); i++) {
de493f1997-04-28Henrik Grubbström (Grubba)  if (lower_case(users[i]) == "any") {
f6d62d1997-03-26Per Hedbor  if(this->register_module()[0] & MODULE_PROXY) patterns += ({ ({ MOD_PROXY_USER, lambda(){ return 1; } }) }); else patterns += ({ ({ MOD_USER, lambda(){ return 1; } }) }); break; } else { users[i & 0x0f] = "(^"+users[i]+"$)"; } if ((i & 0x0f) == 0x0f) { value = users[0..0x0f]*"|"; if(this->register_module()[0] & MODULE_PROXY) { patterns += ({ ({ MOD_PROXY_USER, Regexp(value)->match, }) }); } else { patterns += ({ ({ MOD_USER, Regexp(value)->match, }) }); } } } if (i & 0x0f) { value = users[0..(i-1)&0x0f]*"|"; if(this->register_module()[0] & MODULE_PROXY) { patterns += ({ ({ MOD_PROXY_USER, Regexp(value)->match, }) }); } else { patterns += ({ ({ MOD_USER, Regexp(value)->match, }) }); }
a397fe1996-12-13David Hedbor  }
b1fca01996-11-12Per Hedbor  break;
9579781998-06-29Henrik Grubbström (Grubba)  case "acceptuser": // Short-circuit version of allow user. // NOTE: MOD_PROXY_USER is already short-circuit. value = replace(value, ({ "?", ".", "*" }), ({ ".", "\\.", ".*" })); array(string) users = (value/"," - ({""})); int i; for(i=0; i < sizeof(users); i++) { if (lower_case(users[i]) == "any") { if(this->register_module()[0] & MODULE_PROXY) patterns += ({ ({ MOD_PROXY_USER, lambda(){ return 1; } }) }); else patterns += ({ ({ MOD_ACCEPT_USER, lambda(){ return 1; } }) }); break; } else { users[i & 0x0f] = "(^"+users[i]+"$)"; } if ((i & 0x0f) == 0x0f) { value = users[0..0x0f]*"|"; if(this->register_module()[0] & MODULE_PROXY) { patterns += ({ ({ MOD_PROXY_USER, Regexp(value)->match, }) }); } else { patterns += ({ ({ MOD_ACCEPT_USER, Regexp(value)->match, }) }); } } } if (i & 0x0f) { value = users[0..(i-1)&0x0f]*"|"; if(this->register_module()[0] & MODULE_PROXY) { patterns += ({ ({ MOD_PROXY_USER, Regexp(value)->match, }) }); } else { patterns += ({ ({ MOD_ACCEPT_USER, Regexp(value)->match, }) }); } } break;
de493f1997-04-28Henrik Grubbström (Grubba)  default:
4117501997-08-13Henrik Grubbström (Grubba)  report_error(sprintf("Unknown Security:Patterns directive: " "type=\"%s\"\n", type));
de493f1997-04-28Henrik Grubbström (Grubba)  break;
b1fca01996-11-12Per Hedbor  }
de493f1997-04-28Henrik Grubbström (Grubba)  } else {
4117501997-08-13Henrik Grubbström (Grubba)  report_error(sprintf("Syntax error in Security:Patterns directive: " "line=\"%s\"\n", sl));
b1fca01996-11-12Per Hedbor  } } return patterns; }
7fb7f51999-11-29Per Hedbor mixed stat_file(string f, RequestID id){} mixed find_dir(string f, RequestID id){} mapping(string:array(mixed)) find_dir_stat(string f, RequestID id)
a476711997-10-20Henrik Grubbström (Grubba) {
b275871998-05-23Henrik Grubbström (Grubba)  TRACE_ENTER("find_dir_stat(): \""+f+"\"", 0);
a476711997-10-20Henrik Grubbström (Grubba)  array(string) files = find_dir(f, id); mapping(string:array(mixed)) res = ([]);
0c8b9a1997-10-22Henrik Grubbström (Grubba)  foreach(files || ({}), string fname) {
b275871998-05-23Henrik Grubbström (Grubba)  TRACE_ENTER("stat()'ing "+ f + "/" + fname, 0);
0c8b9a1997-10-22Henrik Grubbström (Grubba)  array(mixed) st = stat_file(f + "/" + fname, id);
a476711997-10-20Henrik Grubbström (Grubba)  if (st) {
0c8b9a1997-10-22Henrik Grubbström (Grubba)  res[fname] = st;
b275871998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("OK"); } else { TRACE_LEAVE("No stat info");
a476711997-10-20Henrik Grubbström (Grubba)  } }
b275871998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a476711997-10-20Henrik Grubbström (Grubba)  return(res); }
7fb7f51999-11-29Per Hedbor mixed real_file(string f, RequestID id){}
b1fca01996-11-12Per Hedbor 
4f4bc11998-02-04Per Hedbor mapping _api_functions = ([]); void add_api_function( string name, function f, void|array(string) types) { _api_functions[name] = ({ f, types }); } mapping api_functions() { return _api_functions; }
4ff8c61999-12-14Martin Nilsson function _rxml_error;
7fb7f51999-11-29Per Hedbor string rxml_error(string tag, string error, RequestID id) {
4ff8c61999-12-14Martin Nilsson  if(_rxml_error) return _rxml_error(tag, error, id); if(id->conf->get_provider("RXMLErrorAlert")) { _rxml_error=id->conf->get_provider("RXMLErrorAlert")->rxml_error; return _rxml_error(tag, error, id); } return ((id->misc->debug||id->prestate->debug)? sprintf("(%s: %s)", capitalize(tag), error):"")+"<false>";
9512ee1999-08-07Martin Nilsson }
48ca161999-05-18Per Hedbor mapping query_tag_callers() { mapping m = ([]); foreach(glob("tag_*", indices( this_object())), string q) if(functionp( this_object()[q] )) m[replace(q[4..], "_", "-")] = this_object()[q]; return m; } mapping query_container_callers() { mapping m = ([]); foreach(glob("container_*", indices( this_object())), string q) if(functionp( this_object()[q] )) m[replace(q[10..], "_", "-")] = this_object()[q]; return m; } mapping query_if_callers() { mapping m = ([]); foreach(glob("if_*", indices( this_object())), string q) if(functionp( this_object()[q] )) m[replace(q[3..], "_", "-")] = this_object()[q]; return m; }
ea062e1999-11-21Martin Nilsson 
1b2b752000-01-07Martin Stjernholm RXML.TagSet query_tag_set()
b9ec252000-01-05Martin Stjernholm { return RXML.TagSet (module_identifier(), filter (rows (this_object(), glob ("Tag*", indices (this_object()))), functionp)); }
12e79e1999-12-07Martin Nilsson mixed get_value_from_file(string path, string index, void|string pre)
ea062e1999-11-21Martin Nilsson {
7fb7f51999-11-29Per Hedbor  Stdio.File file=Stdio.File();
ea062e1999-11-21Martin Nilsson  if(!file->open(path,"r")) return 0;
12e79e1999-12-07Martin Nilsson  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];
ea062e1999-11-21Martin Nilsson }