24c6c12000-02-20Martin Nilsson // A vitual server's main configuration // Copyright © 1996 - 2000, Roxen IS.
e6f83d2000-03-06Peter Bortas // // German translation by Kai Voigt
199d031999-09-05Francesco Chemolli 
a0fbcc2000-04-05Martin Stjernholm constant cvs_version = "$Id: configuration.pike,v 1.297 2000/04/05 17:52:50 mast Exp $";
4d16831999-11-17Per Hedbor constant is_configuration = 1;
b1fca01996-11-12Per Hedbor #include <module.h>
14179b1997-01-29Per Hedbor #include <roxen.h>
c5e0961999-10-04Per Hedbor #include <request_trace.h>
8afc811998-02-04Per Hedbor 
cf0f682000-02-08Per Hedbor inherit "basic_defvar";
c5e0961999-10-04Per Hedbor mapping enabled_modules = ([]);
4d16831999-11-17Per Hedbor mapping(string:array(int)) error_log=([]);
8afc811998-02-04Per Hedbor  #ifdef PROFILE mapping profile_map = ([]); #endif
c7a5f01999-02-16Per Hedbor #define CATCH(P,X) do{mixed e;if(e=catch{X;})report_error("While "+P+"\n"+describe_backtrace(e));}while(0)
18be211998-05-07Henrik Grubbström (Grubba) 
b461641998-10-11Henrik Grubbström (Grubba) // Locale support...
b87aa71998-10-15Henrik Grubbström (Grubba) #define LOCALE LOW_LOCALE->base_server
18be211998-05-07Henrik Grubbström (Grubba) 
199d031999-09-05Francesco Chemolli #ifdef THROTTLING_DEBUG #undef THROTTLING_DEBUG
10c7e11999-12-28Martin Nilsson #define THROTTLING_DEBUG(X) werror("Throttling: "+X+"\n")
199d031999-09-05Francesco Chemolli #else #define THROTTLING_DEBUG(X) #endif
10c7e11999-12-28Martin Nilsson #ifdef REQUEST_DEBUG # define REQUEST_WERR(X) werror("CONFIG: "+X+"\n") #else # define REQUEST_WERR(X) #endif
b1fca01996-11-12Per Hedbor /* A configuration.. */
dfe0362000-03-19Martin Nilsson 
3b17831998-11-22Per Hedbor #include "rxml.pike";
14179b1997-01-29Per Hedbor 
e351dd1999-11-29Per Hedbor object throttler; function store = roxen->store; function retrieve = roxen->retrieve; function remove = roxen->remove; RoxenModule types_module; RoxenModule auth_module; RoxenModule dir_module; function types_fun; function auth_fun;
b1fca01996-11-12Per Hedbor  string name;
10c7e11999-12-28Martin Nilsson mapping variables = ([]);
b1fca01996-11-12Per Hedbor 
1d7d6d2000-02-16Per Hedbor int inited;
c7a5f01999-02-16Per Hedbor 
65c6d22000-03-10Martin Nilsson int config_id; int get_config_id() { if(config_id) return config_id; for(int i=sizeof(roxen->configurations); i;) if(roxen->configurations[--i]->name==name) return config_id=i; }
c7a5f01999-02-16Per Hedbor string get_doc_for( string region, string variable ) {
e351dd1999-11-29Per Hedbor  RoxenModule module;
c7a5f01999-02-16Per Hedbor  if(variable[0] == '_') return 0; if((int)reverse(region)) return 0; if(module = find_module( region )) { if(module->variables[variable]) return module->variables[variable][VAR_NAME]+ "\n"+module->variables[ variable ][ VAR_DOC_STR ]; } if(variables[ variable ]) return variables[variable][VAR_NAME]+ "\n"+variables[ variable ][ VAR_DOC_STR ]; }
c856841998-01-21Henrik Grubbström (Grubba) int defvar(string var, mixed value, string name, int type, string|void doc_str, mixed|void misc, int|function|void not_in_config)
14179b1997-01-29Per Hedbor {
cf0f682000-02-08Per Hedbor  ::defvar( var, value, name, type, doc_str, misc );
10c7e11999-12-28Martin Nilsson 
cf0f682000-02-08Per Hedbor  type &= (VAR_EXPERT | VAR_MORE | VAR_INITIAL | VAR_DEVELOPER);
c5e0961999-10-04Per Hedbor  if (functionp(not_in_config)) if (type)
cf0f682000-02-08Per Hedbor  variables[ var ][ VAR_CONFIGURABLE ] = roxen->ConfigurableWrapper(type, not_in_config)->check;
c5e0961999-10-04Per Hedbor  else
7acb8e1998-07-07Henrik Grubbström (Grubba)  variables[var][ VAR_CONFIGURABLE ] = not_in_config;
10c7e11999-12-28Martin Nilsson  else if (type)
7acb8e1998-07-07Henrik Grubbström (Grubba)  variables[var][ VAR_CONFIGURABLE ] = type;
c5e0961999-10-04Per Hedbor  else if(intp(not_in_config))
7acb8e1998-07-07Henrik Grubbström (Grubba)  variables[var][ VAR_CONFIGURABLE ] = !not_in_config;
df6cd11998-10-13Per Hedbor }
14179b1997-01-29Per Hedbor int definvisvar(string var, mixed value, int type) { return defvar(var, value, "", type, "", 0, 1); }
e351dd1999-11-29Per Hedbor string query_internal_location(RoxenModule|void mod)
5839c31999-01-22Marcus Comstedt {
c5e0961999-10-04Per Hedbor  return QUERY(InternalLoc)+(mod?replace(otomod[mod]||"", "#", "!")+"/":"");
5839c31999-01-22Marcus Comstedt }
b1fca01996-11-12Per Hedbor  string query_name() {
10c7e11999-12-28Martin Nilsson  if(strlen(QUERY(name)))
c5e0961999-10-04Per Hedbor  return QUERY(name);
b1fca01996-11-12Per Hedbor  return name; } string comment() { return QUERY(comment); }
10c7e11999-12-28Martin Nilsson class Priority
27b0e11996-11-26Per Hedbor {
ec91501999-11-23Per Hedbor  string _sprintf() { return "Priority()"; }
e351dd1999-11-29Per Hedbor  array (RoxenModule) url_modules = ({ }); array (RoxenModule) logger_modules = ({ }); array (RoxenModule) location_modules = ({ }); array (RoxenModule) filter_modules = ({ }); array (RoxenModule) last_modules = ({ }); array (RoxenModule) first_modules = ({ }); mapping (string:array(RoxenModule)) file_extension_modules = ([ ]); mapping (RoxenModule:multiset(string)) provider_modules = ([ ]);
38dca81996-12-10Per Hedbor  void stop() {
a8f1b32000-01-31Per Hedbor  foreach(url_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping url modules",m->stop && m->stop());
a8f1b32000-01-31Per Hedbor  foreach(logger_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping logging modules",m->stop && m->stop());
a8f1b32000-01-31Per Hedbor  foreach(filter_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping filter modules",m->stop && m->stop());
a8f1b32000-01-31Per Hedbor  foreach(location_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping location modules",m->stop && m->stop());
a8f1b32000-01-31Per Hedbor  foreach(last_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping last modules",m->stop && m->stop());
a8f1b32000-01-31Per Hedbor  foreach(first_modules, RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping first modules",m->stop && m->stop());
10c7e11999-12-28Martin Nilsson  foreach(indices(provider_modules), RoxenModule m)
c7a5f01999-02-16Per Hedbor  CATCH("stopping provider modules",m->stop && m->stop());
38dca81996-12-10Per Hedbor  } }
b1fca01996-11-12Per Hedbor  /* A 'pri' is one of the ten priority objects. Each one holds a list * of modules for that priority. They are all merged into one list for * performance reasons later on. */
e351dd1999-11-29Per Hedbor array (Priority) allocate_pris()
b1fca01996-11-12Per Hedbor {
c5e0961999-10-04Per Hedbor  return allocate(10, Priority)();
b1fca01996-11-12Per Hedbor }
27b0e11996-11-26Per Hedbor /* For debug and statistics info only */ int requests;
12a9c51997-08-11Henrik Grubbström (Grubba) // Protocol specific statistics. mapping(string:mixed) extra_statistics = ([]);
dc54c41997-08-28Henrik Grubbström (Grubba) mapping(string:mixed) misc = ([]); // Even more statistics.
b1fca01996-11-12Per Hedbor 
48315a1999-11-23Per Hedbor int sent; // Sent data int hsent; // Sent headers int received; // Received data
b1fca01996-11-12Per Hedbor  // Will write a line to the log-file. This will probably be replaced // entirely by log-modules in the future, since this would be much // cleaner.
f406ba1999-11-27Per Hedbor function(string:int) log_function;
b1fca01996-11-12Per Hedbor  // The logging format used. This will probably move the the above // mentioned module in the future. private mapping (string:string) log_format = ([]);
c5e0961999-10-04Per Hedbor // A list of priority objects
e351dd1999-11-29Per Hedbor private array (Priority) pri = allocate_pris();
b1fca01996-11-12Per Hedbor  // All enabled modules in this virtual server.
f569581999-11-23Per Hedbor // The format is "module":{ "copies":([ num:instance, ... ]) } public mapping modules = ([]);
b1fca01996-11-12Per Hedbor  // A mapping from objects to module names
e351dd1999-11-29Per Hedbor public mapping (RoxenModule:string) otomod = ([]);
b1fca01996-11-12Per Hedbor  // Caches to speed up the handling of the module search. // They are all sorted in priority order, and created by the functions // below. private array (function) url_module_cache, last_module_cache; private array (function) logger_module_cache, first_module_cache; private array (function) filter_module_cache; private array (array (string|function)) location_module_cache; private mapping (string:array (function)) file_extension_module_cache=([]);
e351dd1999-11-29Per Hedbor private mapping (string:array (RoxenModule)) provider_module_cache=([]);
b1fca01996-11-12Per Hedbor 
38dca81996-12-10Per Hedbor  // Call stop in all modules. void stop() {
c7a5f01999-02-16Per Hedbor  CATCH("stopping type modules", types_module && types_module->stop && types_module->stop()); CATCH("stopping auth module", auth_module && auth_module->stop && auth_module->stop()); CATCH("stopping directory module", dir_module && dir_module->stop && dir_module->stop());
10c7e11999-12-28Martin Nilsson  for(int i=0; i<10; i++)
c7a5f01999-02-16Per Hedbor  CATCH("stopping priority group",
5b0ec72000-04-03Henrik Grubbström (Grubba)  (pri[i] && pri[i]->stop && pri[i]->stop()));
f86c192000-04-03Henrik Grubbström (Grubba)  CATCH("stopping the logger", log_function && lambda(mixed m){ destruct(m); }(function_object(log_function)));
e62d482000-02-29David Hedbor  foreach( registered_urls, string url ) roxen->unregister_url(url);
38dca81996-12-10Per Hedbor }
41b77c1999-07-15David Hedbor public string type_from_filename( string file, int|void to, string|void myext )
b1fca01996-11-12Per Hedbor {
f28c112000-03-06Martin Nilsson  array(string)|string tmp;
14179b1997-01-29Per Hedbor  if(!types_fun) return to?({ "application/octet-stream", 0 }):"application/octet-stream";
dfe0362000-03-19Martin Nilsson  string ext=myext || Roxen.extension(file);
41b77c1999-07-15David Hedbor 
14179b1997-01-29Per Hedbor  if(tmp = types_fun(ext)) { mixed tmp2,nx; if(tmp[0] == "strip") { tmp2=file/"."; if(sizeof(tmp2) > 2) nx=tmp2[-2]; if(nx && (tmp2=types_fun(nx))) tmp[0] = tmp2[0];
9be5aa1998-07-03Henrik Grubbström (Grubba)  else if(tmp2=types_fun("default")) tmp[0] = tmp2[0];
14179b1997-01-29Per Hedbor  else
9be5aa1998-07-03Henrik Grubbström (Grubba)  tmp[0]="application/octet-stream";
14179b1997-01-29Per Hedbor  }
9be5aa1998-07-03Henrik Grubbström (Grubba)  } else if(!(tmp = types_fun("default"))) { tmp = ({ "application/octet-stream", 0 });
14179b1997-01-29Per Hedbor  }
9be5aa1998-07-03Henrik Grubbström (Grubba)  return to?tmp:tmp[0];
b1fca01996-11-12Per Hedbor }
ae32d01998-03-23David Hedbor // Return an array with all provider modules that provides "provides".
e351dd1999-11-29Per Hedbor array (RoxenModule) get_providers(string provides)
ae32d01998-03-23David Hedbor {
d8b7721998-05-28Henrik Grubbström (Grubba)  // FIXME: Is there any way to clear this cache? // /grubba 1998-05-28
9336a81998-07-09Henrik Grubbström (Grubba)  // - Yes, it is zapped together with the rest in invalidate_cache().
ae32d01998-03-23David Hedbor  if(!provider_module_cache[provides])
10c7e11999-12-28Martin Nilsson  {
ae32d01998-03-23David Hedbor  int i; provider_module_cache[provides] = ({ }); for(i = 9; i >= 0; i--) {
10c7e11999-12-28Martin Nilsson  foreach(indices(pri[i]->provider_modules), RoxenModule d) if(pri[i]->provider_modules[ d ][ provides ])
ae32d01998-03-23David Hedbor  provider_module_cache[provides] += ({ d }); } } return provider_module_cache[provides]; }
14179b1997-01-29Per Hedbor 
ae32d01998-03-23David Hedbor // Return the first provider module that provides "provides".
e351dd1999-11-29Per Hedbor RoxenModule get_provider(string provides)
ae32d01998-03-23David Hedbor {
e351dd1999-11-29Per Hedbor  array (RoxenModule) prov = get_providers(provides);
ae32d01998-03-23David Hedbor  if(sizeof(prov)) return prov[0]; return 0; } // map the function "fun" over all matching provider modules.
bdb8da1998-09-02Johan Schön array(mixed) map_providers(string provides, string fun, mixed ... args)
ae32d01998-03-23David Hedbor {
e351dd1999-11-29Per Hedbor  array (RoxenModule) prov = get_providers(provides);
ae32d01998-03-23David Hedbor  array error;
bdb8da1998-09-02Johan Schön  array a=({ }); mixed m;
10c7e11999-12-28Martin Nilsson  foreach(prov, RoxenModule mod)
9bb8131998-09-12Per Hedbor  {
ae32d01998-03-23David Hedbor  if(!objectp(mod)) continue;
10c7e11999-12-28Martin Nilsson  if(functionp(mod[fun]))
bdb8da1998-09-02Johan Schön  error = catch(m=mod[fun](@args));
24fbd41999-04-21David Hedbor  if(arrayp(error)) { error[0] = "Error in map_providers(): "+error[0];
10c7e11999-12-28Martin Nilsson  report_debug(describe_backtrace(error));
24fbd41999-04-21David Hedbor  }
bdb8da1998-09-02Johan Schön  else
9bb8131998-09-12Per Hedbor  a += ({ m });
18be211998-05-07Henrik Grubbström (Grubba)  error = 0;
ae32d01998-03-23David Hedbor  }
9bb8131998-09-12Per Hedbor  return a;
ae32d01998-03-23David Hedbor } // map the function "fun" over all matching provider modules and // return the first positive response. mixed call_provider(string provides, string fun, mixed ... args) {
10c7e11999-12-28Martin Nilsson  foreach(get_providers(provides), RoxenModule mod)
e351dd1999-11-29Per Hedbor  {
d8b7721998-05-28Henrik Grubbström (Grubba)  function f; if(objectp(mod) && functionp(f = mod[fun])) { mixed error; if (arrayp(error = catch { mixed ret; if (ret = f(@args)) {
c5e0961999-10-04Per Hedbor  return ret;
d8b7721998-05-28Henrik Grubbström (Grubba)  } })) {
24fbd41999-04-21David Hedbor  error[0] = "Error in call_provider(): "+error[0]; throw(error);
d8b7721998-05-28Henrik Grubbström (Grubba)  } }
ae32d01998-03-23David Hedbor  } }
14179b1997-01-29Per Hedbor 
e351dd1999-11-29Per Hedbor array (function) file_extension_modules(string ext, RequestID id)
b1fca01996-11-12Per Hedbor { if(!file_extension_module_cache[ext])
10c7e11999-12-28Martin Nilsson  {
b1fca01996-11-12Per Hedbor  int i; file_extension_module_cache[ext] = ({ }); for(i=9; i>=0; i--) {
e351dd1999-11-29Per Hedbor  array(RoxenModule) d; RoxenModule p;
b1fca01996-11-12Per Hedbor  if(d = pri[i]->file_extension_modules[ext]) foreach(d, p) file_extension_module_cache[ext] += ({ p->handle_file_extension }); } } return file_extension_module_cache[ext]; }
e351dd1999-11-29Per Hedbor array (function) url_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!url_module_cache) { int i; url_module_cache=({ }); for(i=9; i>=0; i--) {
e351dd1999-11-29Per Hedbor  array(RoxenModule) d; RoxenModule p;
b1fca01996-11-12Per Hedbor  if(d=pri[i]->url_modules) foreach(d, p) url_module_cache += ({ p->remap_url }); } } return url_module_cache; }
4f4bc11998-02-04Per Hedbor mapping api_module_cache = ([]);
e351dd1999-11-29Per Hedbor mapping api_functions(void|RequestID id)
4f4bc11998-02-04Per Hedbor { return copy_value(api_module_cache); }
e351dd1999-11-29Per Hedbor array (function) logger_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!logger_module_cache) { int i; logger_module_cache=({ }); for(i=9; i>=0; i--) {
e351dd1999-11-29Per Hedbor  array(RoxenModule) d; RoxenModule p;
b1fca01996-11-12Per Hedbor  if(d=pri[i]->logger_modules) foreach(d, p) if(p->log) logger_module_cache += ({ p->log }); } } return logger_module_cache; }
e351dd1999-11-29Per Hedbor array (function) last_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!last_module_cache) { int i; last_module_cache=({ }); for(i=9; i>=0; i--) {
e351dd1999-11-29Per Hedbor  array(RoxenModule) d; RoxenModule p;
b1fca01996-11-12Per Hedbor  if(d=pri[i]->last_modules) foreach(d, p) if(p->last_resort) last_module_cache += ({ p->last_resort }); } } return last_module_cache; }
ca44e51998-07-02Henrik Grubbström (Grubba) #ifdef __NT__
e351dd1999-11-29Per Hedbor static mixed strip_fork_information(RequestID id)
ca44e51998-07-02Henrik Grubbström (Grubba) { array a = id->not_query/"::"; id->not_query = a[0]; id->misc->fork_information = a[1..];
c5e0961999-10-04Per Hedbor  return 0;
ca44e51998-07-02Henrik Grubbström (Grubba) } #endif /* __NT__ */
e351dd1999-11-29Per Hedbor array (function) first_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!first_module_cache) { int i;
ca44e51998-07-02Henrik Grubbström (Grubba)  first_module_cache=({ #ifdef __NT__ strip_fork_information, // Always first! #endif /* __NT__ */ });
b1fca01996-11-12Per Hedbor  for(i=9; i>=0; i--) {
e351dd1999-11-29Per Hedbor  array(RoxenModule) d; RoxenModule p;
f128901997-08-15Henrik Grubbström (Grubba)  if(d=pri[i]->first_modules) { foreach(d, p) { if(p->first_try) {
b1fca01996-11-12Per Hedbor  first_module_cache += ({ p->first_try });
f128901997-08-15Henrik Grubbström (Grubba)  } } }
b1fca01996-11-12Per Hedbor  } }
f128901997-08-15Henrik Grubbström (Grubba) 
b1fca01996-11-12Per Hedbor  return first_module_cache; }
e351dd1999-11-29Per Hedbor array location_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!location_module_cache) { int i;
8cc31b1997-10-12Henrik Grubbström (Grubba)  array new_location_module_cache=({ });
b1fca01996-11-12Per Hedbor  for(i=9; i>=0; i--) {
10c7e11999-12-28Martin Nilsson  array(RoxenModule) d;
e351dd1999-11-29Per Hedbor  RoxenModule p;
8cc31b1997-10-12Henrik Grubbström (Grubba)  if(d=pri[i]->location_modules) { array level_find_files = ({}); array level_locations = ({}); foreach(d, p) { string location; // FIXME: Should there be a catch() here? if(p->find_file && (location = p->query_location())) { level_find_files += ({ p->find_file }); level_locations += ({ location }); } } sort(level_locations, level_find_files); int j; for (j = sizeof(level_locations); j--;) { // Order after longest path first. new_location_module_cache += ({ ({ level_locations[j], level_find_files[j] }) }); } }
b1fca01996-11-12Per Hedbor  }
8cc31b1997-10-12Henrik Grubbström (Grubba)  location_module_cache = new_location_module_cache;
b1fca01996-11-12Per Hedbor  } return location_module_cache; }
e351dd1999-11-29Per Hedbor array filter_modules(RequestID id)
b1fca01996-11-12Per Hedbor { if(!filter_module_cache) { int i; filter_module_cache=({ }); for(i=9; i>=0; i--) {
10c7e11999-12-28Martin Nilsson  array(RoxenModule) d;
e351dd1999-11-29Per Hedbor  RoxenModule p;
b1fca01996-11-12Per Hedbor  if(d=pri[i]->filter_modules) foreach(d, p) if(p->filter) filter_module_cache+=({ p->filter }); } } return filter_module_cache; }
3bb38c2000-01-20Martin Bähr static string cached_hostname = gethostname();
1c78232000-03-13Per Hedbor class LogFile
b1fca01996-11-12Per Hedbor {
1c78232000-03-13Per Hedbor  Stdio.File fd; int opened; string fname; void do_open() {
5b0ec72000-04-03Henrik Grubbström (Grubba)  mixed parent; if (catch { parent = function_object(object_program(this_object())); } || !parent) { /* Our parent (aka the configuration) has been destructed. * Time to die. */ remove_call_out(do_open); remove_call_out(do_close); destruct(); return; }
6513612000-03-14Per Hedbor  string ff = fname; mapping m = localtime(time()); m->year += 1900; /* Adjust for years being counted since 1900 */ m->mon++; /* Adjust for months being counted 0-11 */ if(m->mon < 10) m->mon = "0"+m->mon; if(m->mday < 10) m->mday = "0"+m->mday; if(m->hour < 10) m->hour = "0"+m->hour; ff = replace(fname,({"%d","%m","%y","%h", "%H" }), ({ (string)m->mday, (string)(m->mon), (string)(m->year),(string)m->hour, cached_hostname, })); mkdirhier( ff ); fd = open( ff, "wac" ); if(!fd) { remove_call_out( do_open ); call_out( do_open, 120 ); report_error("Failed to open logfile "+fname+" " #if constant(strerror) "(" + strerror(errno()) + ")" #endif "\n"); return; }
1c78232000-03-13Per Hedbor  opened = 1;
6513612000-03-14Per Hedbor  remove_call_out( do_open ); call_out( do_open, 1800 );
1c78232000-03-13Per Hedbor  } void do_close() { destruct( fd ); opened = 0; }
14179b1997-01-29Per Hedbor 
6513612000-03-14Per Hedbor  int write( string what )
1c78232000-03-13Per Hedbor  {
6513612000-03-14Per Hedbor  if( !opened ) do_open(); if( !opened ) return 0;
1c78232000-03-13Per Hedbor  remove_call_out( do_close ); call_out( do_close, 10.0 );
6513612000-03-14Per Hedbor  return fd->write( what );
1c78232000-03-13Per Hedbor  }
10c7e11999-12-28Martin Nilsson 
1c78232000-03-13Per Hedbor  static void create( string f )
b1fca01996-11-12Per Hedbor  {
6513612000-03-14Per Hedbor  fname = f;
1c78232000-03-13Per Hedbor  opened = 0; } } void init_log_file() { if(log_function) { // Free the old one. destruct(function_object(log_function)); log_function = 0; } // Only try to open the log file if logging is enabled!! if(query("Log")) { string logfile = query("LogFile");
f7d9811997-09-12Per Hedbor  if(strlen(logfile))
1c78232000-03-13Per Hedbor  log_function = LogFile( logfile )->write; }
b1fca01996-11-12Per Hedbor }
14179b1997-01-29Per Hedbor // Parse the logging format strings. private inline string fix_logging(string s)
b1fca01996-11-12Per Hedbor {
14179b1997-01-29Per Hedbor  string pre, post, c; sscanf(s, "%*[\t ]", s); s = replace(s, ({"\\t", "\\n", "\\r" }), ({"\t", "\n", "\r" }));
62eac81997-10-03Henrik Grubbström (Grubba) 
1c78232000-03-13Per Hedbor  s = String.trim_whites( s );
14179b1997-01-29Per Hedbor  while(sscanf(s, "%s$char(%d)%s", pre, c, post)==3) s=sprintf("%s%c%s", pre, c, post); while(sscanf(s, "%s$wchar(%d)%s", pre, c, post)==3) s=sprintf("%s%2c%s", pre, c, post); while(sscanf(s, "%s$int(%d)%s", pre, c, post)==3) s=sprintf("%s%4c%s", pre, c, post); if(!sscanf(s, "%s$^%s", pre, post)) s+="\n"; else s=pre+post; return s;
b1fca01996-11-12Per Hedbor }
14179b1997-01-29Per Hedbor private void parse_log_formats() { string b; array foo=query("LogFormat")/"\n"; foreach(foo, b) if(strlen(b) && b[0] != '#' && sizeof(b/":")>1)
62eac81997-10-03Henrik Grubbström (Grubba)  log_format[(b/":")[0]] = fix_logging((b/":")[1..]*":");
14179b1997-01-29Per Hedbor }
b1fca01996-11-12Per Hedbor 
14179b1997-01-29Per Hedbor // Really write an entry to the log. private void write_to_log( string host, string rest, string oh, function fun )
b1fca01996-11-12Per Hedbor {
14179b1997-01-29Per Hedbor  int s; if(!host) host=oh; if(!stringp(host)) host = "error:no_host";
71c7b11998-03-02Henrik Grubbström (Grubba)  else host = (host/" ")[0]; // In case it's an IP we don't want the port.
14179b1997-01-29Per Hedbor  if(fun) fun(replace(rest, "$host", host));
b1fca01996-11-12Per Hedbor }
14179b1997-01-29Per Hedbor // Logging format support functions. nomask private inline string host_ip_to_int(string s) { int a, b, c, d; sscanf(s, "%d.%d.%d.%d", a, b, c, d); return sprintf("%c%c%c%c",a, b, c, d); }
b1fca01996-11-12Per Hedbor 
14179b1997-01-29Per Hedbor nomask private inline string unsigned_to_bin(int a) { return sprintf("%4c", a); } nomask private inline string unsigned_short_to_bin(int a) { return sprintf("%2c", a); } nomask private inline string extract_user(string from) { array tmp; if (!from || sizeof(tmp = from/":")<2) return "-";
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  return tmp[0]; // username only, no password }
f406ba1999-11-27Per Hedbor public void log(mapping file, RequestID request_id)
14179b1997-01-29Per Hedbor {
e5bad21998-02-10Per Hedbor // _debug(2);
14179b1997-01-29Per Hedbor  string a; string form; function f; foreach(logger_modules(request_id), f) // Call all logging functions if(f(request_id,file))return;
0976901998-11-26Henrik Grubbström (Grubba)  if(!log_function || !request_id) return;// No file is open for logging.
14179b1997-01-29Per Hedbor 
dfe0362000-03-19Martin Nilsson  if(QUERY(NoLog) && Roxen._match(request_id->remoteaddr, QUERY(NoLog)))
14179b1997-01-29Per Hedbor  return;
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(!(form=log_format[(string)file->error])) form = log_format["*"];
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(!form) return;
10c7e11999-12-28Martin Nilsson  form=replace(form, ({
14179b1997-01-29Per Hedbor  "$ip_number", "$bin-ip_number", "$cern_date",
dfb4ec1999-05-20Francesco Chemolli  "$bin-date", "$method", "$resource", "$full_resource", "$protocol",
14179b1997-01-29Per Hedbor  "$response", "$bin-response", "$length", "$bin-length", "$referer", "$user_agent", "$user", "$user_id",
d9624c1998-04-03Henrik Grubbström (Grubba)  "$request-time"
10c7e11999-12-28Martin Nilsson  }),
f406ba1999-11-27Per Hedbor  ({
14179b1997-01-29Per Hedbor  (string)request_id->remoteaddr,
71c7b11998-03-02Henrik Grubbström (Grubba)  host_ip_to_int(request_id->remoteaddr),
dfe0362000-03-19Martin Nilsson  Roxen.cern_http_date(time(1)),
71c7b11998-03-02Henrik Grubbström (Grubba)  unsigned_to_bin(time(1)), (string)request_id->method,
dfe0362000-03-19Martin Nilsson  Roxen.http_encode_string((string)request_id->not_query), Roxen.http_encode_string((string)request_id->raw_url),
71c7b11998-03-02Henrik Grubbström (Grubba)  (string)request_id->prot, (string)(file->error||200), unsigned_short_to_bin(file->error||200), (string)(file->len>=0?file->len:"?"), unsigned_to_bin(file->len), (string) (sizeof(request_id->referer||({}))?request_id->referer[0]:"-"),
dfe0362000-03-19Martin Nilsson  Roxen.http_encode_string(sizeof(request_id->client||({}))?request_id->client*" ":"-"),
71c7b11998-03-02Henrik Grubbström (Grubba)  extract_user(request_id->realauth),
f406ba1999-11-27Per Hedbor  request_id->cookies->RoxenUserID||"0",
d9624c1998-04-03Henrik Grubbström (Grubba)  (string)(time(1)-request_id->time)
71c7b11998-03-02Henrik Grubbström (Grubba)  }));
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(search(form, "host") != -1) roxen->ip_to_host(request_id->remoteaddr, write_to_log, form, request_id->remoteaddr, log_function); else log_function(form);
e5bad21998-02-10Per Hedbor // _debug(0);
14179b1997-01-29Per Hedbor } // These are here for statistics and debug reasons only. public string status()
b1fca01996-11-12Per Hedbor {
14179b1997-01-29Per Hedbor  float tmp;
b1fca01996-11-12Per Hedbor  string res="";
b461641998-10-11Henrik Grubbström (Grubba)  float dt = (float)(time(1) - roxen->start_time + 1);
14179b1997-01-29Per Hedbor 
b461641998-10-11Henrik Grubbström (Grubba)  res = "<table>";
10c7e11999-12-28Martin Nilsson  res += LOCALE->config_status(((float)sent/(1024.0*1024.0)),
8f5abe1999-12-11Per Hedbor  (((float)sent)/(1024.0*1024.0)/dt) * 8192.0,
10c7e11999-12-28Martin Nilsson  ((float)hsent)/(1024.0*1024.0),
8f5abe1999-12-11Per Hedbor  requests,
10c7e11999-12-28Martin Nilsson  (((float)requests * 60.0)/dt),
8f5abe1999-12-11Per Hedbor  ((float)received)/(1024.0*1024.0));
dc54c41997-08-28Henrik Grubbström (Grubba)  if (!zero_type(misc->ftp_users)) {
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->ftp_status(misc->ftp_users, (((float)misc->ftp_users*(float)60.0)/dt), misc->ftp_users_now);
dc54c41997-08-28Henrik Grubbström (Grubba)  }
926d1a1997-08-31Henrik Grubbström (Grubba)  res += "</table><p>\n\n";
12a9c51997-08-11Henrik Grubbström (Grubba) 
c5e0961999-10-04Per Hedbor  if ((extra_statistics->ftp) && (extra_statistics->ftp->commands)) {
12a9c51997-08-11Henrik Grubbström (Grubba)  // FTP statistics.
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->ftp_statistics() + "<br>\n"
12a9c51997-08-11Henrik Grubbström (Grubba)  "<ul><table>\n"; foreach(sort(indices(extra_statistics->ftp->commands)), string cmd) {
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->ftp_stat_line(upper_case(cmd), extra_statistics->ftp->commands[cmd]);
12a9c51997-08-11Henrik Grubbström (Grubba)  } res += "</table></ul>\n"; }
10c7e11999-12-28Martin Nilsson 
12a9c51997-08-11Henrik Grubbström (Grubba)  return res;
14179b1997-01-29Per Hedbor }
e351dd1999-11-29Per Hedbor public array(string) userinfo(string u, RequestID|void id)
14179b1997-01-29Per Hedbor { if(auth_module) return auth_module->userinfo(u);
b461641998-10-11Henrik Grubbström (Grubba)  else report_warning(sprintf("userinfo(): %s\n" "%s\n", LOCALE->no_auth_module(), describe_backtrace(backtrace())));
14179b1997-01-29Per Hedbor }
e351dd1999-11-29Per Hedbor public array(string) userlist(RequestID|void id)
14179b1997-01-29Per Hedbor { if(auth_module) return auth_module->userlist();
b461641998-10-11Henrik Grubbström (Grubba)  else report_warning(sprintf("userlist(): %s\n" "%s\n", LOCALE->no_auth_module(), describe_backtrace(backtrace())));
14179b1997-01-29Per Hedbor }
e351dd1999-11-29Per Hedbor public array(string) user_from_uid(int u, RequestID|void id)
14179b1997-01-29Per Hedbor { if(auth_module) return auth_module->user_from_uid(u);
b461641998-10-11Henrik Grubbström (Grubba)  else report_warning(sprintf("user_from_uid(): %s\n" "%s\n", LOCALE->no_auth_module(), describe_backtrace(backtrace())));
14179b1997-01-29Per Hedbor }
e351dd1999-11-29Per Hedbor public string last_modified_by(Stdio.File file, RequestID id)
6103bc1999-10-09Henrik Grubbström (Grubba) {
9f9fc32000-02-17Per Hedbor  array(int) s;
6103bc1999-10-09Henrik Grubbström (Grubba)  int uid;
9f9fc32000-02-17Per Hedbor  array u;
10c7e11999-12-28Martin Nilsson 
6103bc1999-10-09Henrik Grubbström (Grubba)  if(objectp(file)) s=file->stat(); if(!s || sizeof(s)<5) return "A. Nonymous"; uid=s[5]; u=user_from_uid(uid, id); if(u) return u[0]; return "A. Nonymous"; }
14179b1997-01-29Per Hedbor  // Some clients does _not_ handle the magic 'internal-gopher-...'. // So, lets do it here instead. private mapping internal_gopher_image(string from) { sscanf(from, "%s.gif", from); sscanf(from, "%s.jpg", from); from -= "."; // Disallow "internal-gopher-..", it won't really do much harm, but a list of // all files in '..' might be retrieved (that is, the actual directory // file was sent to the browser)
1c78232000-03-13Per Hedbor  Stdio.File f = lopen("roxen-images/dir/"+from+".gif","r"); if (f) {
06026c1999-10-19Henrik Grubbström (Grubba)  return (["file":f, "type":"image/gif"]); } else { // File not found. return 0; }
14179b1997-01-29Per Hedbor } private static int nest = 0;
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor #ifdef MODULE_LEVEL_SECURITY private mapping misc_cache=([]);
e351dd1999-11-29Per Hedbor int|mapping check_security(function a, RequestID id, void|int slevel)
14179b1997-01-29Per Hedbor { array level; array seclevels;
2028af1997-07-07Henrik Grubbström (Grubba)  int ip_ok = 0; // Unknown
12a9c51997-08-11Henrik Grubbström (Grubba)  int auth_ok = 0; // Unknown // NOTE: // ip_ok and auth_ok are three-state variables. // Valid contents for them are: // 0 Unknown state -- No such restriction encountered yet. // 1 May be bad -- Restriction encountered, and test failed. // ~0 OK -- Test passed.
1935351997-04-28Henrik Grubbström (Grubba) 
14179b1997-01-29Per Hedbor  if(!(seclevels = misc_cache[ a ]))
3b17831998-11-22Per Hedbor  if(function_object(a)->query_seclevels) misc_cache[ a ] = seclevels = ({ function_object(a)->query_seclevels(), function_object(a)->query("_seclvl"), function_object(a)->query("_sec_group") }); else misc_cache[ a ] = seclevels = ({({}),0,"foo" });
14179b1997-01-29Per Hedbor  if(slevel && (seclevels[1] > slevel)) // "Trustlevel" to low. return 1;
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(!sizeof(seclevels[0])) return 0; // Ok if there are no patterns.
18be211998-05-07Henrik Grubbström (Grubba)  mixed err; err = catch {
2028af1997-07-07Henrik Grubbström (Grubba)  foreach(seclevels[0], level) {
cc6d7c1997-07-22Henrik Grubbström (Grubba)  switch(level[0]) { case MOD_ALLOW: // allow ip=...
2028af1997-07-07Henrik Grubbström (Grubba)  if(level[1](id->remoteaddr)) {
cc6d7c1997-07-22Henrik Grubbström (Grubba)  ip_ok = ~0; // Match. It's ok.
2028af1997-07-07Henrik Grubbström (Grubba)  } else {
cc6d7c1997-07-22Henrik Grubbström (Grubba)  ip_ok |= 1; // IP may be bad.
2028af1997-07-07Henrik Grubbström (Grubba)  }
12a9c51997-08-11Henrik Grubbström (Grubba)  break;
a8f1b32000-01-31Per Hedbor 
cc6d7c1997-07-22Henrik Grubbström (Grubba)  case MOD_DENY: // deny ip=...
b461641998-10-11Henrik Grubbström (Grubba)  // FIXME: LOCALE?
a75a321997-05-14Henrik Grubbström (Grubba)  if(level[1](id->remoteaddr))
dfe0362000-03-19Martin Nilsson  return Roxen.http_low_answer(403, "<h2>Access forbidden</h2>");
12a9c51997-08-11Henrik Grubbström (Grubba)  break;
14179b1997-01-29Per Hedbor 
cc6d7c1997-07-22Henrik Grubbström (Grubba)  case MOD_USER: // allow user=...
12a9c51997-08-11Henrik Grubbström (Grubba)  if(id->auth && id->auth[0] && level[1](id->auth[1])) { auth_ok = ~0; // Match. It's ok. } else { auth_ok |= 1; // Auth may be bad. } break;
a8f1b32000-01-31Per Hedbor 
cc6d7c1997-07-22Henrik Grubbström (Grubba)  case MOD_PROXY_USER: // allow user=...
12a9c51997-08-11Henrik Grubbström (Grubba)  if (ip_ok != 1) { // IP is OK as of yet.
10c7e11999-12-28Martin Nilsson  if(id->misc->proxyauth && id->misc->proxyauth[0] &&
12a9c51997-08-11Henrik Grubbström (Grubba)  level[1](id->misc->proxyauth[1])) return 0;
dfe0362000-03-19Martin Nilsson  return Roxen.http_proxy_auth_required(seclevels[2]);
12a9c51997-08-11Henrik Grubbström (Grubba)  } else { // Bad IP.
c5e0961999-10-04Per Hedbor  return 1;
12a9c51997-08-11Henrik Grubbström (Grubba)  }
7be80e1998-06-29Henrik Grubbström (Grubba)  break; case MOD_ACCEPT: // accept ip=... // Short-circuit version on allow. if(level[1](id->remoteaddr)) { // Match. It's ok.
c5e0961999-10-04Per Hedbor  return 0;
7be80e1998-06-29Henrik Grubbström (Grubba)  } else { ip_ok |= 1; // IP may be bad. } break; case MOD_ACCEPT_USER: // accept user=... // Short-circuit version on allow. if(id->auth && id->auth[0] && level[1](id->auth[1])) { // Match. It's ok.
c5e0961999-10-04Per Hedbor  return 0;
7be80e1998-06-29Henrik Grubbström (Grubba)  } else { if (id->auth) { auth_ok |= 1; // Auth may be bad. } else { // No auth yet, get some.
dfe0362000-03-19Martin Nilsson  return Roxen.http_auth_required(seclevels[2]);
7be80e1998-06-29Henrik Grubbström (Grubba)  } } break;
14179b1997-01-29Per Hedbor  }
2028af1997-07-07Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor  };
18be211998-05-07Henrik Grubbström (Grubba)  if (err) {
b461641998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->module_security_error(describe_backtrace(err)));
c5e0961999-10-04Per Hedbor  return 1;
18be211998-05-07Henrik Grubbström (Grubba)  }
12a9c51997-08-11Henrik Grubbström (Grubba)  if (ip_ok == 1) { // Bad IP.
c5e0961999-10-04Per Hedbor  return 1;
12a9c51997-08-11Henrik Grubbström (Grubba)  } else { // IP OK, or no IP restrictions. if (auth_ok == 1) { // Bad authentification. // Query for authentification.
dfe0362000-03-19Martin Nilsson  return Roxen.http_auth_required(seclevels[2]);
12a9c51997-08-11Henrik Grubbström (Grubba)  } else { // No auth required, or authentification OK.
c5e0961999-10-04Per Hedbor  return 0;
12a9c51997-08-11Henrik Grubbström (Grubba)  }
2028af1997-07-07Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor } #endif // Empty all the caches above.
8cc31b1997-10-12Henrik Grubbström (Grubba) void invalidate_cache()
14179b1997-01-29Per Hedbor { last_module_cache = 0; filter_module_cache = 0; first_module_cache = 0; url_module_cache = 0; location_module_cache = 0; logger_module_cache = 0; file_extension_module_cache = ([]);
ae32d01998-03-23David Hedbor  provider_module_cache = ([]);
14179b1997-01-29Per Hedbor #ifdef MODULE_LEVEL_SECURITY if(misc_cache) misc_cache = ([ ]); #endif }
ec058c1998-07-04Henrik Grubbström (Grubba) // Empty all the caches above AND the ones in the loaded modules. void clear_memory_caches() { invalidate_cache();
10c7e11999-12-28Martin Nilsson  foreach(indices(otomod), RoxenModule m) if (m && m->clear_memory_caches) if (mixed err = catch( m->clear_memory_caches() ))
b461641998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> clear_memory_cache_error(otomod[m], describe_backtrace(err)));
ec058c1998-07-04Henrik Grubbström (Grubba) }
fc94331997-10-25Per Hedbor string draw_saturation_bar(int hue,int brightness, int where) {
e351dd1999-11-29Per Hedbor  Image.Image bar=Image.Image(30,256);
fc94331997-10-25Per Hedbor  for(int i=0;i<128;i++) { int j = i*2; bar->line(0,j,29,j,@hsv_to_rgb(hue,255-j,brightness)); bar->line(0,j+1,29,j+1,@hsv_to_rgb(hue,255-j,brightness)); } where = 255-where; bar->line(0,where,29,where, 255,255,255);
4c6df91999-11-25Jonas Wallden  return Image.GIF.encode(bar);
fc94331997-10-25Per Hedbor }
14179b1997-01-29Per Hedbor // Inspired by the internal-gopher-... thingie, this is the images
a6ef1f2000-03-28Johan Sundström // from the administration interface. :-)
14179b1997-01-29Per Hedbor private mapping internal_roxen_image(string from) {
c5e0961999-10-04Per Hedbor  // changed 970820 by js to allow for jpeg images
2b658c2000-02-07Per Hedbor  // changed 20000203 by per to allow for xcf and png images
14179b1997-01-29Per Hedbor  sscanf(from, "%s.gif", from); sscanf(from, "%s.jpg", from);
2b658c2000-02-07Per Hedbor  sscanf(from, "%s.xcf", from); sscanf(from, "%s.png", from);
fc94331997-10-25Per Hedbor 
1c78232000-03-13Per Hedbor  // Automatically generated colorbar. Used by wizard code...
fc94331997-10-25Per Hedbor  int hue,bright,w; if(sscanf(from, "%*s:%d,%d,%d", hue, bright,w)==4)
dfe0362000-03-19Martin Nilsson  return Roxen.http_string_answer(draw_saturation_bar(hue,bright,w),"image/gif");
fc94331997-10-25Per Hedbor 
2b658c2000-02-07Per Hedbor  Stdio.File f;
1c78232000-03-13Per Hedbor  if(f = lopen("roxen-images/"+from+".gif", "r"))
06026c1999-10-19Henrik Grubbström (Grubba)  return (["file":f, "type":"image/gif"]);
1c78232000-03-13Per Hedbor  if(f = lopen("roxen-images/"+from+".jpg", "r"))
06026c1999-10-19Henrik Grubbström (Grubba)  return (["file":f, "type":"image/jpeg"]);
1c78232000-03-13Per Hedbor  if(f = lopen("roxen-images/"+from+".png", "r"))
2b658c2000-02-07Per Hedbor  return (["file":f, "type":"image/png"]);
1c78232000-03-13Per Hedbor  if(f = lopen("roxen-images/"+from+".xcf", "r"))
2b658c2000-02-07Per Hedbor  return (["file":f, "type":"image/x-gimp-image"]); // File not found. return 0;
14179b1997-01-29Per Hedbor } mapping (mixed:function|int) locks = ([]); #ifdef THREADS
e5bad21998-02-10Per Hedbor // import Thread;
e6aff01997-05-25Henrik Grubbström (Grubba) 
55a89e1997-09-14Per Hedbor mapping locked = ([]), thread_safe = ([]);
e351dd1999-11-29Per Hedbor mixed _lock(object|function f)
14179b1997-01-29Per Hedbor { object key;
1fab6f1997-09-03Henrik Grubbström (Grubba)  function|int l;
55a89e1997-09-14Per Hedbor 
1fab6f1997-09-03Henrik Grubbström (Grubba)  if (functionp(f)) { f = function_object(f); }
55a89e1997-09-14Per Hedbor  if (l = locks[f]) { if (l != -1) {
1fab6f1997-09-03Henrik Grubbström (Grubba)  // Allow recursive locks.
beb1f21998-05-23Mattias Wingstedt  catch{
10c7e11999-12-28Martin Nilsson  //werror("lock %O\n", f);
55a89e1997-09-14Per Hedbor  locked[f]++;
1fab6f1997-09-03Henrik Grubbström (Grubba)  key = l();
beb1f21998-05-23Mattias Wingstedt  };
55a89e1997-09-14Per Hedbor  } else thread_safe[f]++;
1fab6f1997-09-03Henrik Grubbström (Grubba)  } else if (f->thread_safe) { locks[f]=-1;
55a89e1997-09-14Per Hedbor  thread_safe[f]++;
14179b1997-01-29Per Hedbor  } else {
55a89e1997-09-14Per Hedbor  if (!locks[f]) {
1fab6f1997-09-03Henrik Grubbström (Grubba)  // Needed to avoid race-condition.
e5bad21998-02-10Per Hedbor  l = Thread.Mutex()->lock;
1fab6f1997-09-03Henrik Grubbström (Grubba)  if (!locks[f]) { locks[f]=l; }
14179b1997-01-29Per Hedbor  }
10c7e11999-12-28Martin Nilsson  //werror("lock %O\n", f);
55a89e1997-09-14Per Hedbor  locked[f]++;
1fab6f1997-09-03Henrik Grubbström (Grubba)  key = l();
b1fca01996-11-12Per Hedbor  }
14179b1997-01-29Per Hedbor  return key;
b1fca01996-11-12Per Hedbor }
14179b1997-01-29Per Hedbor #define LOCK(X) key=_lock(X)
d7b0871997-08-31Per Hedbor #define UNLOCK() do{key=0;}while(0)
14179b1997-01-29Per Hedbor #else #define LOCK(X)
c95bd51998-01-30Henrik Grubbström (Grubba) #define UNLOCK()
14179b1997-01-29Per Hedbor #endif
a1334f1998-02-20Mirar (Pontus Hagland) string examine_return_mapping(mapping m) { string res; if (m->extra_heads) m->extra_heads=mkmapping(Array.map(indices(m->extra_heads), lower_case), values(m->extra_heads)); else m->extra_heads=([]); switch (m->error||200) { case 302: // redirect
10c7e11999-12-28Martin Nilsson  if (m->extra_heads &&
a1334f1998-02-20Mirar (Pontus Hagland)  (m->extra_heads->location))
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE->returned_redirect_to(m->extra_heads->location);
a1334f1998-02-20Mirar (Pontus Hagland)  else
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE->returned_redirect_no_location();
a1334f1998-02-20Mirar (Pontus Hagland)  break; case 401: if (m->extra_heads["www-authenticate"])
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE-> returned_authenticate(m->extra_heads["www-authenticate"]);
a1334f1998-02-20Mirar (Pontus Hagland)  else
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE->returned_auth_failed();
a1334f1998-02-20Mirar (Pontus Hagland)  break; case 200:
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE->returned_ok();
a1334f1998-02-20Mirar (Pontus Hagland)  break;
a8f1b32000-01-31Per Hedbor 
a1334f1998-02-20Mirar (Pontus Hagland)  default:
b461641998-10-11Henrik Grubbström (Grubba)  res = LOCALE->returned_error(m->error);
a1334f1998-02-20Mirar (Pontus Hagland)  } if (!zero_type(m->len)) if (m->len<0)
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->returned_no_data();
a1334f1998-02-20Mirar (Pontus Hagland)  else
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->returned_bytes(m->len);
a1334f1998-02-20Mirar (Pontus Hagland)  else if (stringp(m->data))
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->returned_bytes(strlen(m->data));
a1334f1998-02-20Mirar (Pontus Hagland)  else if (objectp(m->file)) if (catch { array a=m->file->stat();
b461641998-10-11Henrik Grubbström (Grubba)  res += LOCALE->returned_bytes(a[1]-m->file->tell()); }) res += LOCALE->returned_unknown_bytes();
a1334f1998-02-20Mirar (Pontus Hagland) 
b461641998-10-11Henrik Grubbström (Grubba)  if (m->data) res += LOCALE->returned_static_data();
7b80781999-02-15Marcus Comstedt  else if (m->file) res += LOCALE->returned_open_file();
a1334f1998-02-20Mirar (Pontus Hagland) 
b461641998-10-11Henrik Grubbström (Grubba)  if (stringp(m->extra_heads["http-content-type"]) || stringp(m->type)) { res += LOCALE->returned_type(m->type); }
a1334f1998-02-20Mirar (Pontus Hagland)  res+="<br>"; return res; }
c5e0961999-10-04Per Hedbor  // The function that actually tries to find the data requested. All // modules are mapped, in order, and the first one that returns a // suitable responce is used.
e351dd1999-11-29Per Hedbor mapping|int low_get_file(RequestID id, int|void no_magic)
14179b1997-01-29Per Hedbor { #ifdef MODULE_LEVEL_SECURITY int slevel; #endif #ifdef THREADS object key; #endif
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->request_for(id->not_query), 0);
14179b1997-01-29Per Hedbor  string file=id->not_query; string loc; function funp; mixed tmp, tmp2; mapping|object fid; if(!no_magic) {
41b77c1999-07-15David Hedbor #ifndef NO_INTERNAL_HACK string type;
10c7e11999-12-28Martin Nilsson  // No, this is not beautiful... :)
41b77c1999-07-15David Hedbor  // min length == 17 (/internal-roxen-?..) // This will save some time indeed. if(sizeof(file) > 17 && (file[0] == '/') && sscanf(file, "%*s/internal-%s-%[^/]", type, loc) == 3)
14179b1997-01-29Per Hedbor  {
41b77c1999-07-15David Hedbor  switch(type) { case "gopher":
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->magic_internal_gopher());
14179b1997-01-29Per Hedbor  return internal_gopher_image(loc);
41b77c1999-07-15David Hedbor  case "spinner": case "roxen":
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->magic_internal_roxen());
14179b1997-01-29Per Hedbor  return internal_roxen_image(loc);
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  } #endif
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(id->prestate->diract && dir_module) { LOCK(dir_module);
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->directory_module(), dir_module);
14179b1997-01-29Per Hedbor  tmp = dir_module->parse_directory(id); UNLOCK();
10c7e11999-12-28Martin Nilsson  if(mappingp(tmp))
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
41d0f91998-02-20Per Hedbor  return tmp; } TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  }
5839c31999-01-22Marcus Comstedt 
10c7e11999-12-28Martin Nilsson  if(!search(file, QUERY(InternalLoc)))
5839c31999-01-22Marcus Comstedt  { TRACE_ENTER(LOCALE->magic_internal_module_location(), 0);
e351dd1999-11-29Per Hedbor  RoxenModule module;
5839c31999-01-22Marcus Comstedt  string name, rest; function find_internal; if(2==sscanf(file[strlen(QUERY(InternalLoc))..], "%s/%s", name, rest) && (module = find_module(replace(name, "!", "#"))) && (find_internal = module->find_internal)) { #ifdef MODULE_LEVEL_SECURITY if(tmp2 = check_security(find_internal, id, slevel)) if(intp(tmp2)) { TRACE_LEAVE(LOCALE->module_access_denied()); find_internal = 0; } else { TRACE_LEAVE(""); TRACE_LEAVE(LOCALE->request_denied()); return tmp2; } #endif
41b77c1999-07-15David Hedbor  if(find_internal)
5839c31999-01-22Marcus Comstedt  {
8f46d91999-01-22Marcus Comstedt  TRACE_ENTER(LOCALE->calling_find_internal(), find_internal);
5839c31999-01-22Marcus Comstedt  LOCK(find_internal); fid=find_internal( rest, id ); UNLOCK(); TRACE_LEAVE(LOCALE->find_internal_returned(fid)); if(fid) { if(mappingp(fid)) { TRACE_LEAVE(""); TRACE_LEAVE(examine_return_mapping(fid)); return fid; } else { #ifdef MODULE_LEVEL_SECURITY int oslevel = slevel; slevel = misc_cache[ find_internal ][1]; // misc_cache from // check_security id->misc->seclevel = slevel; #endif if(objectp(fid)) TRACE_LEAVE(LOCALE->returned_fd() #ifdef MODULE_LEVEL_SECURITY +(slevel != oslevel? LOCALE->seclevel_is_now(slevel):"") #endif +"."); else TRACE_LEAVE(LOCALE->returned_directory_indicator() #ifdef MODULE_LEVEL_SECURITY +(oslevel != slevel? LOCALE->seclevel_is_now(slevel):"") #endif ); } } else TRACE_LEAVE(""); } else TRACE_LEAVE(""); } else TRACE_LEAVE(""); }
14179b1997-01-29Per Hedbor  } // Well, this just _might_ be somewhat over-optimized, since it is
10c7e11999-12-28Martin Nilsson  // quite unreadable, but, you cannot win them all..
5839c31999-01-22Marcus Comstedt  if(!fid) {
14179b1997-01-29Per Hedbor #ifdef URL_MODULES
f128901997-08-15Henrik Grubbström (Grubba)  // Map URL-modules
5839c31999-01-22Marcus Comstedt  foreach(url_modules(id), funp)
41d0f91998-02-20Per Hedbor  {
5839c31999-01-22Marcus Comstedt  LOCK(funp); TRACE_ENTER(LOCALE->url_module(), funp); tmp=funp( id, file ); UNLOCK();
10c7e11999-12-28Martin Nilsson  if(mappingp(tmp))
5839c31999-01-22Marcus Comstedt  { TRACE_LEAVE(""); TRACE_LEAVE(LOCALE->returning_data()); return tmp; } if(objectp( tmp )) { array err;
a8f1b32000-01-31Per Hedbor 
5839c31999-01-22Marcus Comstedt  nest ++; err = catch { if( nest < 20 ) tmp = (id->conf || this_object())->low_get_file( tmp, no_magic ); else { TRACE_LEAVE(LOCALE->too_deep_recursion()); error("Too deep recursion in roxen::get_file() while mapping " +file+".\n"); } }; nest = 0; if(err) throw(err); TRACE_LEAVE(""); TRACE_LEAVE(LOCALE->returning_data()); return tmp; }
41d0f91998-02-20Per Hedbor  TRACE_LEAVE(""); }
14179b1997-01-29Per Hedbor #endif
c5e0961999-10-04Per Hedbor 
5839c31999-01-22Marcus Comstedt  foreach(location_modules(id), tmp)
14179b1997-01-29Per Hedbor  {
5839c31999-01-22Marcus Comstedt  loc = tmp[0];
41b77c1999-07-15David Hedbor  if(!search(file, loc))
5839c31999-01-22Marcus Comstedt  { TRACE_ENTER(LOCALE->location_module(loc), tmp[1]);
df8d711998-02-27Per Hedbor #ifdef MODULE_LEVEL_SECURITY
5839c31999-01-22Marcus Comstedt  if(tmp2 = check_security(tmp[1], id, slevel)) if(intp(tmp2)) { TRACE_LEAVE(LOCALE->module_access_denied()); continue; } else { TRACE_LEAVE(""); TRACE_LEAVE(LOCALE->request_denied()); return tmp2; }
14179b1997-01-29Per Hedbor #endif
5839c31999-01-22Marcus Comstedt  TRACE_ENTER(LOCALE->calling_find_file(), 0); LOCK(tmp[1]); fid=tmp[1]( file[ strlen(loc) .. ] + id->extra_extension, id); UNLOCK();
b8b1072000-03-24Per Hedbor  // LOCALE->find_file_returned(fid) TRACE_LEAVE("");
5839c31999-01-22Marcus Comstedt  if(fid)
14179b1997-01-29Per Hedbor  {
5839c31999-01-22Marcus Comstedt  id->virtfile = loc;
a8f1b32000-01-31Per Hedbor 
5839c31999-01-22Marcus Comstedt  if(mappingp(fid)) { TRACE_LEAVE(""); TRACE_LEAVE(examine_return_mapping(fid)); return fid; } else {
14179b1997-01-29Per Hedbor #ifdef MODULE_LEVEL_SECURITY
5839c31999-01-22Marcus Comstedt  int oslevel = slevel; slevel = misc_cache[ tmp[1] ][1]; // misc_cache from // check_security id->misc->seclevel = slevel;
14179b1997-01-29Per Hedbor #endif
5839c31999-01-22Marcus Comstedt  if(objectp(fid)) TRACE_LEAVE(LOCALE->returned_fd()
41d0f91998-02-20Per Hedbor #ifdef MODULE_LEVEL_SECURITY
5839c31999-01-22Marcus Comstedt  +(slevel != oslevel? LOCALE->seclevel_is_now(slevel):"")
41d0f91998-02-20Per Hedbor #endif
a8f1b32000-01-31Per Hedbor 
5839c31999-01-22Marcus Comstedt  +"."); else TRACE_LEAVE(LOCALE->returned_directory_indicator()
41d0f91998-02-20Per Hedbor #ifdef MODULE_LEVEL_SECURITY
5839c31999-01-22Marcus Comstedt  +(oslevel != slevel? LOCALE->seclevel_is_now(slevel):"")
41d0f91998-02-20Per Hedbor #endif
5839c31999-01-22Marcus Comstedt  ); break; } } else TRACE_LEAVE("");
41b77c1999-07-15David Hedbor  } else if(strlen(loc)-1==strlen(file) && file+"/" == loc) {
10c7e11999-12-28Martin Nilsson  // This one is here to allow accesses to /local, even if
5839c31999-01-22Marcus Comstedt  // the mountpoint is /local/. It will slow things down, but...
41b77c1999-07-15David Hedbor  TRACE_ENTER(LOCALE->automatic_redirect_to_location(), tmp[1]); TRACE_LEAVE(LOCALE->returning_data());
a8f1b32000-01-31Per Hedbor 
41b77c1999-07-15David Hedbor  // Keep query (if any). /* FIXME: Should probably keep prestate etc. * /grubba 1999-01-14 */
dfe0362000-03-19Martin Nilsson  string new_query = Roxen.http_encode_string(id->not_query) + "/" +
41b77c1999-07-15David Hedbor  (id->query?("?"+id->query):"");
a8f1b32000-01-31Per Hedbor 
dfe0362000-03-19Martin Nilsson  return Roxen.http_redirect(new_query, id);
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  } }
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(fid == -1) {
41d0f91998-02-20Per Hedbor  if(no_magic) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->no_magic());
41d0f91998-02-20Per Hedbor  return -1; }
14179b1997-01-29Per Hedbor  if(dir_module) { LOCK(dir_module);
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->directory_module(), dir_module);
14179b1997-01-29Per Hedbor  fid = dir_module->parse_directory(id); UNLOCK(); } else
41d0f91998-02-20Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->no_directory_module());
14179b1997-01-29Per Hedbor  return 0;
41d0f91998-02-20Per Hedbor  }
10c7e11999-12-28Martin Nilsson  if(mappingp(fid))
41d0f91998-02-20Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
41d0f91998-02-20Per Hedbor  return (mapping)fid; }
14179b1997-01-29Per Hedbor  }
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  // Map the file extensions, but only if there is a file...
41b77c1999-07-15David Hedbor  if(objectp(fid) &&
dfe0362000-03-19Martin Nilsson  (tmp = file_extension_modules(loc = Roxen.extension(id->not_query, id), id))) {
14179b1997-01-29Per Hedbor  foreach(tmp, funp) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->extension_module(loc), funp);
14179b1997-01-29Per Hedbor #ifdef MODULE_LEVEL_SECURITY if(tmp=check_security(funp, id, slevel)) if(intp(tmp)) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->module_access_denied());
14179b1997-01-29Per Hedbor  continue; } else
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->permission_denied());
14179b1997-01-29Per Hedbor  return tmp;
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor #endif LOCK(funp); tmp=funp(fid, loc, id); UNLOCK(); if(tmp) { if(!objectp(tmp))
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
14179b1997-01-29Per Hedbor  return tmp;
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  if(fid)
41b77c1999-07-15David Hedbor  destruct(fid);
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_new_open_file());
14179b1997-01-29Per Hedbor  fid = tmp; break;
41d0f91998-02-20Per Hedbor  } else TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  }
41b77c1999-07-15David Hedbor  }
14179b1997-01-29Per Hedbor  if(objectp(fid)) {
41b77c1999-07-15David Hedbor  if(stringp(id->extension)) {
14179b1997-01-29Per Hedbor  id->not_query += id->extension;
dfe0362000-03-19Martin Nilsson  loc = Roxen.extension(id->not_query, id);
41b77c1999-07-15David Hedbor  }
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->content_type_module(), types_module);
41b77c1999-07-15David Hedbor  tmp=type_from_filename(id->not_query, 1, loc);
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(tmp?LOCALE->returned_mime_type(tmp[0],tmp[1]): LOCALE->missing_type());
14179b1997-01-29Per Hedbor  if(tmp)
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  return ([ "file":fid, "type":tmp[0], "encoding":tmp[1] ]);
10c7e11999-12-28Martin Nilsson  }
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  return ([ "file":fid, ]); }
41d0f91998-02-20Per Hedbor  if(!fid)
c7a5f01999-02-16Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_not_found());
c7a5f01999-02-16Per Hedbor  }
41d0f91998-02-20Per Hedbor  else
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
14179b1997-01-29Per Hedbor  return fid; }
c7a5f01999-02-16Per Hedbor 
e351dd1999-11-29Per Hedbor mixed handle_request( RequestID id )
c7a5f01999-02-16Per Hedbor { function funp; mixed file;
10c7e11999-12-28Martin Nilsson  REQUEST_WERR("handle_request()");
c7a5f01999-02-16Per Hedbor  foreach(first_modules(id), funp) {
10c7e11999-12-28Martin Nilsson  if(file = funp( id ))
c7a5f01999-02-16Per Hedbor  break;
cfda381999-03-28Henrik Grubbström (Grubba)  if(id->conf != this_object()) {
10c7e11999-12-28Martin Nilsson  REQUEST_WERR("handle_request(): Redirected (2)");
c7a5f01999-02-16Per Hedbor  return id->conf->handle_request(id);
cfda381999-03-28Henrik Grubbström (Grubba)  }
c7a5f01999-02-16Per Hedbor  }
fd8b151999-05-19David Hedbor  if(!mappingp(file) && !mappingp(file = get_file(id)))
c7a5f01999-02-16Per Hedbor  { mixed ret; foreach(last_modules(id), funp) if(ret = funp(id)) break;
cfda381999-03-28Henrik Grubbström (Grubba)  if (ret == 1) {
10c7e11999-12-28Martin Nilsson  REQUEST_WERR("handle_request(): Recurse");
c7a5f01999-02-16Per Hedbor  return handle_request(id);
cfda381999-03-28Henrik Grubbström (Grubba)  }
c7a5f01999-02-16Per Hedbor  file = ret; }
10c7e11999-12-28Martin Nilsson  REQUEST_WERR("handle_request(): Done");
c7a5f01999-02-16Per Hedbor  return file; }
576c112000-03-07Martin Stjernholm mixed get_file(RequestID id, int|void no_magic, int|void internal_get)
14179b1997-01-29Per Hedbor {
576c112000-03-07Martin Stjernholm  int orig_internal_get = id->misc->internal_get; id->misc->internal_get = internal_get;
14179b1997-01-29Per Hedbor  mixed res, res2; function tmp; res = low_get_file(id, no_magic); // finally map all filter type modules. // Filter modules are like TYPE_LAST modules, but they get called // for _all_ files. foreach(filter_modules(id), tmp)
41d0f91998-02-20Per Hedbor  {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->filter_module(), tmp);
14179b1997-01-29Per Hedbor  if(res2=tmp(res,id)) { if(res && res->file && (res2->file != res->file)) destruct(res->file);
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->rewrote_result());
14179b1997-01-29Per Hedbor  res=res2;
41d0f91998-02-20Per Hedbor  } else TRACE_LEAVE(""); }
576c112000-03-07Martin Stjernholm  id->misc->internal_get = orig_internal_get;
14179b1997-01-29Per Hedbor  return res; }
b6a9042000-03-17Martin Nilsson public array(string) find_dir(string file, RequestID id)
14179b1997-01-29Per Hedbor { string loc;
b6a9042000-03-17Martin Nilsson  array dir = ({ }); array|mapping|object tmp;
29a8071998-08-21David Hedbor  array | mapping d;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->list_directory(file), 0);
c7a5f01999-02-16Per Hedbor // file=replace(file, "//", "/");
10c7e11999-12-28Martin Nilsson 
1935351997-04-28Henrik Grubbström (Grubba)  if(file[0] != '/') file = "/" + file;
f128901997-08-15Henrik Grubbström (Grubba) #ifdef URL_MODULES
fc0e5d1997-08-26Henrik Grubbström (Grubba) #ifdef THREADS object key; #endif
f128901997-08-15Henrik Grubbström (Grubba)  // Map URL-modules foreach(url_modules(id), function funp) { string of = id->not_query; id->not_query = file; LOCK(funp);
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->url_module(), funp);
f128901997-08-15Henrik Grubbström (Grubba)  tmp=funp( id, file ); UNLOCK(); if(mappingp( tmp )) { id->not_query=of;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_no_thanks());
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
f128901997-08-15Henrik Grubbström (Grubba)  return 0; } if(objectp( tmp )) { array err; nest ++;
10c7e11999-12-28Martin Nilsson 
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->recursing());
f128901997-08-15Henrik Grubbström (Grubba)  file = id->not_query; err = catch { if( nest < 20 ) tmp = (id->conf || this_object())->find_dir( file, id ); else error("Too deep recursion in roxen::find_dir() while mapping " +file+".\n"); }; nest = 0;
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
f128901997-08-15Henrik Grubbström (Grubba)  if(err) throw(err); return tmp; } id->not_query=of; }
a86c6c1997-09-22Henrik Grubbström (Grubba) #endif /* URL_MODULES */
f128901997-08-15Henrik Grubbström (Grubba) 
14179b1997-01-29Per Hedbor  foreach(location_modules(id), tmp) { loc = tmp[0];
a476711997-10-20Henrik Grubbström (Grubba)  if(!search(file, loc)) { /* file == loc + subpath */
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), tmp[1]);
a78a591997-04-28Henrik Grubbström (Grubba) #ifdef MODULE_LEVEL_SECURITY
41d0f91998-02-20Per Hedbor  if(check_security(tmp[1], id)) {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->permission_denied());
41d0f91998-02-20Per Hedbor  continue; }
a78a591997-04-28Henrik Grubbström (Grubba) #endif
8dbe2d1997-05-26Henrik Grubbström (Grubba)  if(d=function_object(tmp[1])->find_dir(file[strlen(loc)..], id))
41d0f91998-02-20Per Hedbor  {
29a8071998-08-21David Hedbor  if(mappingp(d)) {
10c7e11999-12-28Martin Nilsson  if(d->files) {
29a8071998-08-21David Hedbor  dir |= d->files;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->got_exclusive_dir()); TRACE_LEAVE(LOCALE->returning_file_list(sizeof(dir)));
29a8071998-08-21David Hedbor  return dir; } else TRACE_LEAVE(""); } else {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->got_files());
29a8071998-08-21David Hedbor  dir |= d; }
41d0f91998-02-20Per Hedbor  } else TRACE_LEAVE("");
a476711997-10-20Henrik Grubbström (Grubba)  } else if((search(loc, file)==0) && (loc[strlen(file)-1]=='/') && (loc[0]==loc[-1]) && (loc[-1]=='/') &&
6c67c81998-02-28Johan Schön  (function_object(tmp[1])->stat_file(".", id))) {
a476711997-10-20Henrik Grubbström (Grubba)  /* loc == file + "/" + subpath + "/"
24fa081998-02-28Henrik Grubbström (Grubba)  * and stat_file(".") returns non-zero.
a476711997-10-20Henrik Grubbström (Grubba)  */
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), tmp[1]);
a476711997-10-20Henrik Grubbström (Grubba)  loc=loc[strlen(file)..]; sscanf(loc, "%s/", loc); dir += ({ loc });
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->added_module_mountpoint());
14179b1997-01-29Per Hedbor  } } if(sizeof(dir))
41d0f91998-02-20Per Hedbor  {
cfda381999-03-28Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_file_list(sizeof(dir)));
14179b1997-01-29Per Hedbor  return dir;
10c7e11999-12-28Martin Nilsson  }
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_no_dir());
14179b1997-01-29Per Hedbor }
10c7e11999-12-28Martin Nilsson // Stat a virtual file.
14179b1997-01-29Per Hedbor 
e351dd1999-11-29Per Hedbor public array(int) stat_file(string file, RequestID id)
14179b1997-01-29Per Hedbor { string loc; array s, tmp;
c5e0961999-10-04Per Hedbor #ifdef THREADS object key; #endif
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->stat_file(file), 0);
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  file=replace(file, "//", "/"); // "//" is really "/" here...
f128901997-08-15Henrik Grubbström (Grubba)  #ifdef URL_MODULES // Map URL-modules foreach(url_modules(id), function funp) { string of = id->not_query; id->not_query = file;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->url_module(), funp);
f128901997-08-15Henrik Grubbström (Grubba)  LOCK(funp); tmp=funp( id, file ); UNLOCK(); if(mappingp( tmp )) { id->not_query = of;
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_no_thanks());
f128901997-08-15Henrik Grubbström (Grubba)  return 0; } if(objectp( tmp )) { file = id->not_query; array err; nest ++;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->recursing());
f128901997-08-15Henrik Grubbström (Grubba)  err = catch { if( nest < 20 ) tmp = (id->conf || this_object())->stat_file( file, id ); else error("Too deep recursion in roxen::stat_file() while mapping " +file+".\n"); }; nest = 0; if(err) throw(err);
8fd51f1998-03-01Per Hedbor  TRACE_LEAVE("");
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
f128901997-08-15Henrik Grubbström (Grubba)  return tmp; }
8fd51f1998-03-01Per Hedbor  TRACE_LEAVE("");
f128901997-08-15Henrik Grubbström (Grubba)  id->not_query = of; } #endif
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  // Map location-modules. foreach(location_modules(id), tmp) { loc = tmp[0]; if((file == loc) || ((file+"/")==loc))
41d0f91998-02-20Per Hedbor  {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), tmp[1]); TRACE_LEAVE(LOCALE->exact_match());
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
223fd12000-01-27Johan Sundström  return ({ 0775, -3, 0, 0, 0, 0, 0 });
41d0f91998-02-20Per Hedbor  }
10c7e11999-12-28Martin Nilsson  if(!search(file, loc))
14179b1997-01-29Per Hedbor  {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), tmp[1]);
a78a591997-04-28Henrik Grubbström (Grubba) #ifdef MODULE_LEVEL_SECURITY
41d0f91998-02-20Per Hedbor  if(check_security(tmp[1], id)) {
8fd51f1998-03-01Per Hedbor  TRACE_LEAVE("");
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->permission_denied());
41d0f91998-02-20Per Hedbor  continue; }
a78a591997-04-28Henrik Grubbström (Grubba) #endif
14179b1997-01-29Per Hedbor  if(s=function_object(tmp[1])->stat_file(file[strlen(loc)..], id))
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->stat_ok());
14179b1997-01-29Per Hedbor  return s;
41d0f91998-02-20Per Hedbor  } TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  } }
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_not_found());
14179b1997-01-29Per Hedbor }
e8790b1998-02-19Per Hedbor class StringFile { string data; int offset;
ec91501999-11-23Per Hedbor  string _sprintf() { return "StringFile("+strlen(data)+","+offset+")"; }
e8790b1998-02-19Per Hedbor  string read(int nbytes) {
6d93981998-11-30Per Hedbor  if(!nbytes) { offset = strlen(data); return data; }
41d0f91998-02-20Per Hedbor  string d = data[offset..offset+nbytes-1];
e8790b1998-02-19Per Hedbor  offset += strlen(d); return d; } void write(mixed ... args) {
3bb38c2000-01-20Martin Bähr  throw( ({ "File not open for write\n", backtrace() }) );
e8790b1998-02-19Per Hedbor  } void seek(int to) { offset = to; } void create(string d) { data = d; }
41d0f91998-02-20Per Hedbor 
e8790b1998-02-19Per Hedbor } // this is not as trivial as it sounds. Consider gtext. :-)
e351dd1999-11-29Per Hedbor public array open_file(string fname, string mode, RequestID id)
e8790b1998-02-19Per Hedbor { object oc = id->conf; string oq = id->not_query; function funp;
3a4b9a1999-12-27Martin Nilsson  mapping|int(0..1) file;
cd7ea41998-12-14Peter Bortas  id->not_query = fname;
c7a5f01999-02-16Per Hedbor 
e8790b1998-02-19Per Hedbor  foreach(oc->first_modules(), funp)
10c7e11999-12-28Martin Nilsson  if(file = funp( id ))
e8790b1998-02-19Per Hedbor  break;
10c7e11999-12-28Martin Nilsson  else if(id->conf != oc)
e8790b1998-02-19Per Hedbor  { return open_file(fname, mode,id); } fname = id->not_query; if(search(mode, "R")!=-1) // raw (as in not parsed..) { string f; mode -= "R"; if(f = real_file(fname, id))
41d0f91998-02-20Per Hedbor  {
9bb8131998-09-12Per Hedbor  // werror("opening "+fname+" in raw mode.\n");
e8790b1998-02-19Per Hedbor  return ({ open(f, mode), ([]) });
41d0f91998-02-20Per Hedbor  }
2380831998-02-22Per Hedbor // return ({ 0, (["error":302]) });
e8790b1998-02-19Per Hedbor  } if(mode=="r") { if(!file) { file = oc->get_file( id );
f920ce1998-10-02Henrik Grubbström (Grubba)  if(!file) {
41d0f91998-02-20Per Hedbor  foreach(oc->last_modules(), funp) if(file = funp( id ))
e8790b1998-02-19Per Hedbor  break;
f920ce1998-10-02Henrik Grubbström (Grubba)  if (file == 1) { // Recurse. return open_file(id->not_query, mode, id); } }
e8790b1998-02-19Per Hedbor  } if(!mappingp(file)) { if(id->misc->error_code)
dfe0362000-03-19Martin Nilsson  file = Roxen.http_low_answer(id->misc->error_code, "Failed" );
2380831998-02-22Per Hedbor  else if(id->method!="GET"&&id->method != "HEAD"&&id->method!="POST")
dfe0362000-03-19Martin Nilsson  file = Roxen.http_low_answer(501, "Not implemented.");
576c112000-03-07Martin Stjernholm  else {
dfe0362000-03-19Martin Nilsson  file = Roxen.http_low_answer(404,
52e0822000-03-07Henrik Grubbström (Grubba)  parse_rxml(
576c112000-03-07Martin Stjernholm #ifdef OLD_RXML_COMPAT
52e0822000-03-07Henrik Grubbström (Grubba)  replace(query("ZNoSuchFile"), ({ "$File", "$Me" }), ({ "&page.virtfile;",
ee80572000-03-08Martin Nilsson  "&roxen.server;"
52e0822000-03-07Henrik Grubbström (Grubba)  })),
576c112000-03-07Martin Stjernholm #else
52e0822000-03-07Henrik Grubbström (Grubba)  query("ZNoSuchFile"),
576c112000-03-07Martin Stjernholm #endif
52e0822000-03-07Henrik Grubbström (Grubba)  id));
576c112000-03-07Martin Stjernholm  }
e8790b1998-02-19Per Hedbor  id->not_query = oq;
10c7e11999-12-28Martin Nilsson 
e8790b1998-02-19Per Hedbor  return ({ 0, file }); }
10c7e11999-12-28Martin Nilsson  if( file->data )
e8790b1998-02-19Per Hedbor  { file->file = StringFile(file->data); m_delete(file, "data");
10c7e11999-12-28Martin Nilsson  }
e8790b1998-02-19Per Hedbor  id->not_query = oq; return ({ file->file, file }); } id->not_query = oq;
001ae71998-10-11Henrik Grubbström (Grubba)  return ({ 0, (["error":501, "data":"Not implemented"]) });
e8790b1998-02-19Per Hedbor }
e351dd1999-11-29Per Hedbor public mapping(string:array(mixed)) find_dir_stat(string file, RequestID id)
a86c6c1997-09-22Henrik Grubbström (Grubba) { string loc;
a476711997-10-20Henrik Grubbström (Grubba)  mapping(string:array(mixed)) dir = ([]); mixed d, tmp;
a86c6c1997-09-22Henrik Grubbström (Grubba) 
c7a5f01999-02-16Per Hedbor 
a86c6c1997-09-22Henrik Grubbström (Grubba)  file=replace(file, "//", "/");
10c7e11999-12-28Martin Nilsson 
a86c6c1997-09-22Henrik Grubbström (Grubba)  if(file[0] != '/') file = "/" + file;
ae60b61998-05-23Henrik Grubbström (Grubba)  // FIXME: Should I append a "/" to file if missing?
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->find_dir_stat(file), 0);
ae60b61998-05-23Henrik Grubbström (Grubba) 
a86c6c1997-09-22Henrik Grubbström (Grubba) #ifdef URL_MODULES #ifdef THREADS object key; #endif // Map URL-modules foreach(url_modules(id), function funp) { string of = id->not_query; id->not_query = file; LOCK(funp);
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->url_module(), funp);
a86c6c1997-09-22Henrik Grubbström (Grubba)  tmp=funp( id, file ); UNLOCK(); if(mappingp( tmp )) { id->not_query=of;
3510fb1997-11-09Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
10c7e11999-12-28Martin Nilsson  werror("conf->find_dir_stat(\"%s\"): url_module returned mapping:%O\n", file, tmp);
3510fb1997-11-09Henrik Grubbström (Grubba) #endif /* MODULE_DEBUG */
07014c1999-05-24Per Hedbor  TRACE_LEAVE(LOCALE->returned_mapping()+sprintf("%O", tmp)); TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  return 0; } if(objectp( tmp )) { array err; nest ++;
10c7e11999-12-28Martin Nilsson 
a86c6c1997-09-22Henrik Grubbström (Grubba)  file = id->not_query; err = catch { if( nest < 20 ) tmp = (id->conf || this_object())->find_dir_stat( file, id );
ae60b61998-05-23Henrik Grubbström (Grubba)  else {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->too_deep_recursion());
a86c6c1997-09-22Henrik Grubbström (Grubba)  error("Too deep recursion in roxen::find_dir_stat() while mapping " +file+".\n");
ae60b61998-05-23Henrik Grubbström (Grubba)  }
a86c6c1997-09-22Henrik Grubbström (Grubba)  }; nest = 0; if(err) throw(err);
3510fb1997-11-09Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
10c7e11999-12-28Martin Nilsson  werror("conf->find_dir_stat(\"%s\"): url_module returned object:\n", file);
3510fb1997-11-09Henrik Grubbström (Grubba) #endif /* MODULE_DEBUG */
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_object()); TRACE_LEAVE(LOCALE->returning_it());
ae60b61998-05-23Henrik Grubbström (Grubba)  return tmp; // FIXME: Return 0 instead?
a86c6c1997-09-22Henrik Grubbström (Grubba)  } id->not_query=of;
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  } #endif /* URL_MODULES */ foreach(location_modules(id), tmp) { loc = tmp[0];
a476711997-10-20Henrik Grubbström (Grubba) 
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), 0);
a476711997-10-20Henrik Grubbström (Grubba)  /* Note that only new entries are added. */
a86c6c1997-09-22Henrik Grubbström (Grubba)  if(!search(file, loc)) {
a476711997-10-20Henrik Grubbström (Grubba)  /* file == loc + subpath */
a86c6c1997-09-22Henrik Grubbström (Grubba) #ifdef MODULE_LEVEL_SECURITY if(check_security(tmp[1], id)) continue; #endif
e351dd1999-11-29Per Hedbor  RoxenModule c = function_object(tmp[1]);
a86c6c1997-09-22Henrik Grubbström (Grubba)  string f = file[strlen(loc)..]; if (c->find_dir_stat) {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->has_find_dir_stat(), 0);
a86c6c1997-09-22Henrik Grubbström (Grubba)  if (d = c->find_dir_stat(f, id)) {
07014c1999-05-24Per Hedbor  TRACE_ENTER(LOCALE->returned_mapping()+sprintf("%O", d),c);
a476711997-10-20Henrik Grubbström (Grubba)  dir = d | dir;
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  }
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  } else if(d = c->find_dir(f, id)) {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->returned_array(), 0);
10c7e11999-12-28Martin Nilsson  dir = mkmapping(d, Array.map(d, lambda(string fn)
e351dd1999-11-29Per Hedbor  { return c->stat_file(f + fn, id); })) | dir;
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  }
a476711997-10-20Henrik Grubbström (Grubba)  } else if(search(loc, file)==0 && loc[strlen(file)-1]=='/' && (loc[0]==loc[-1]) && loc[-1]=='/' &&
8935ad1998-03-30Johan Schön  (function_object(tmp[1])->stat_file(".", id))) {
a476711997-10-20Henrik Grubbström (Grubba)  /* loc == file + "/" + subpath + "/"
8935ad1998-03-30Johan Schön  * and stat_file(".") returns non-zero.
a476711997-10-20Henrik Grubbström (Grubba)  */
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->file_on_mountpoint_path(file, loc), 0);
a476711997-10-20Henrik Grubbström (Grubba)  loc=loc[strlen(file)..]; sscanf(loc, "%s/", loc); if (!dir[loc]) { dir[loc] = ({ 0775, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
a86c6c1997-09-22Henrik Grubbström (Grubba)  }
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  }
ae60b61998-05-23Henrik Grubbström (Grubba)  TRACE_LEAVE("");
a86c6c1997-09-22Henrik Grubbström (Grubba)  } if(sizeof(dir)) return dir; }
14179b1997-01-29Per Hedbor  // Access a virtual file?
e351dd1999-11-29Per Hedbor public array access(string file, RequestID id)
14179b1997-01-29Per Hedbor { string loc; array s, tmp;
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  file=replace(file, "//", "/"); // "//" is really "/" here...
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  // Map location-modules. foreach(location_modules(id), tmp) { loc = tmp[0];
4770421999-11-22Henrik Grubbström (Grubba)  if((file+"/")==loc) { #ifdef MODULE_LEVEL_SECURITY if(check_security(tmp[1], id)) continue; #endif if(s=function_object(tmp[1])->access("", id)) return s; } else if(!search(file, loc)) {
14179b1997-01-29Per Hedbor #ifdef MODULE_LEVEL_SECURITY if(check_security(tmp[1], id)) continue; #endif if(s=function_object(tmp[1])->access(file[strlen(loc)..], id)) return s; } }
4770421999-11-22Henrik Grubbström (Grubba)  return 0;
14179b1997-01-29Per Hedbor } // Return the _real_ filename of a virtual file, if any.
e351dd1999-11-29Per Hedbor public string real_file(string file, RequestID id)
14179b1997-01-29Per Hedbor { string loc; string s; array tmp; file=replace(file, "//", "/"); // "//" is really "/" here...
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(!id) error("No id passed to real_file"); // Map location-modules. foreach(location_modules(id), tmp) { loc = tmp[0];
10c7e11999-12-28Martin Nilsson  if(!search(file, loc))
14179b1997-01-29Per Hedbor  { #ifdef MODULE_LEVEL_SECURITY if(check_security(tmp[1], id)) continue; #endif
c5e0961999-10-04Per Hedbor  if(s=function_object(tmp[1])->real_file(file[strlen(loc)..], id))
14179b1997-01-29Per Hedbor  return s; } } } // Convenience functions used in quite a lot of modules. Tries to // read a file into memory, and then returns the resulting string. // NOTE: A 'file' can be a cgi script, which will be executed, resulting in // a horrible delay.
646f722000-03-07Martin Stjernholm // // Unless the not_internal flag is set, this tries to get an external // or internal file. Here "internal" means a file that never should be // sent directly as a request response. E.g. an internal redirect to a // different file is still considered "external" since its contents is // sent directly to the client. Internal requests are recognized by // the id->misc->internal_get flag.
10c7e11999-12-28Martin Nilsson int|string try_get_file(string s, RequestID id,
646f722000-03-07Martin Stjernholm  int|void status, int|void nocache, int|void not_internal)
14179b1997-01-29Per Hedbor {
646f722000-03-07Martin Stjernholm  string res, q, cache_key;
e351dd1999-11-29Per Hedbor  RequestID fake_id;
14179b1997-01-29Per Hedbor  mapping m;
10c7e11999-12-28Martin Nilsson  if(!objectp(id))
14179b1997-01-29Per Hedbor  error("No ID passed to 'try_get_file'\n");
e351dd1999-11-29Per Hedbor  // id->misc->common makes it possible to pass information to // the originating request. if ( !id->misc ) id->misc = ([]); if ( !id->misc->common ) id->misc->common = ([]);
10c7e11999-12-28Martin Nilsson 
e351dd1999-11-29Per Hedbor  fake_id = id->clone_me();
10c7e11999-12-28Martin Nilsson 
e351dd1999-11-29Per Hedbor  fake_id->misc->common = id->misc->common;
646da22000-03-20Martin Stjernholm  s = Roxen.fix_relative (s, id);
646f722000-03-07Martin Stjernholm  if(!id->pragma["no-cache"] && !nocache && (!id->auth || !id->auth[0])) { cache_key = s + "\0" + id->request_headers->cookie + "\0" + id->request_headers["user-agent"];
db02e52000-03-20Martin Nilsson  if(res = cache_lookup("file:"+name, cache_key))
14179b1997-01-29Per Hedbor  return res;
646f722000-03-07Martin Stjernholm  }
14179b1997-01-29Per Hedbor 
4e0a532000-03-20Martin Stjernholm  if (fake_id->scan_for_query) // FIXME: If we're using e.g. ftp this doesn't exist. But the // right solution might be that clone_me() in an ftp id object // returns a vanilla (i.e. http) id instead when this function is // used. s = fake_id->scan_for_query (s);
14179b1997-01-29Per Hedbor  fake_id->raw_url=s; fake_id->not_query=s;
c927a02000-03-18Martin Stjernholm  if(!(m = get_file(fake_id,0,!not_internal))) {
4cd5e82000-03-20Martin Stjernholm  // Might be a PATH_INFO type URL. m_delete (fake_id->misc, "path_info");
e1e86d2000-03-20Martin Stjernholm  array a = open_file( s, "r", fake_id ); if(a && a[0]) { m = a[1]; m->file = a[0]; } else { destruct (fake_id); return 0; }
c927a02000-03-18Martin Stjernholm  } destruct (fake_id);
889d031999-10-04Per Hedbor 
3bb38c2000-01-20Martin Bähr  if (!mappingp(m) && !objectp(m)) { report_error("try_get_file(%O, %O, %O, %O): m = %O is not a mapping.\n", s, id, status, nocache, m); return 0; }
3510fb1997-11-09Henrik Grubbström (Grubba)  if (!(< 0, 200, 201, 202, 203 >)[m->error]) return 0;
10c7e11999-12-28Martin Nilsson 
3510fb1997-11-09Henrik Grubbström (Grubba)  if(status) return 1;
10c7e11999-12-28Martin Nilsson  if(m->data)
a22f6f1999-05-12Per Hedbor  res = m->data;
10c7e11999-12-28Martin Nilsson  else
a22f6f1999-05-12Per Hedbor  res="";
14179b1997-01-29Per Hedbor  m->data = 0;
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(m->file) {
3a4d7e1997-09-03Per Hedbor  res += m->file->read();
14179b1997-01-29Per Hedbor  destruct(m->file); m->file = 0; }
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  if(m->raw) { res -= "\r"; if(!sscanf(res, "%*s\n\n%s", res)) sscanf(res, "%*s\n%s", res); }
646f722000-03-07Martin Stjernholm  if (cache_key)
db02e52000-03-20Martin Nilsson  cache_set("file:"+name, cache_key, res);
14179b1997-01-29Per Hedbor  return res; } // Is 'what' a file in our virtual filesystem?
e351dd1999-11-29Per Hedbor int(0..1) is_file(string what, RequestID id)
14179b1997-01-29Per Hedbor { return !!stat_file(what, id); }
c5e0961999-10-04Per Hedbor array registered_urls = ({});
14179b1997-01-29Per Hedbor void start(int num) {
c5e0961999-10-04Per Hedbor  // Note: This is run as root if roxen is started as root foreach( query( "URLs" )-registered_urls, string url ) { registered_urls += ({ url }); roxenp()->register_url( url, this_object() );
14179b1997-01-29Per Hedbor  }
c5e0961999-10-04Per Hedbor  foreach( registered_urls-query("URLs"), string url ) { registered_urls -= ({ url }); roxenp()->unregister_url( url );
14179b1997-01-29Per Hedbor  } }
e7e6031999-11-05Per Hedbor void save_me() { save_one( 0 ); }
c45e3f2000-02-16Per Hedbor // Save this configuration. If all is included, save all configuration // global variables as well, otherwise only all module variables.
14179b1997-01-29Per Hedbor void save(int|void all) { if(all) {
3f628a1999-12-09Martin Stjernholm  store("spider#0", variables, 0, this_object());
14179b1997-01-29Per Hedbor  start(2); }
10c7e11999-12-28Martin Nilsson 
3f628a1999-12-09Martin Stjernholm  foreach(indices(modules), string modname)
14179b1997-01-29Per Hedbor  {
3f628a1999-12-09Martin Stjernholm  foreach(indices(modules[modname]->copies), int i)
14179b1997-01-29Per Hedbor  {
3f628a1999-12-09Martin Stjernholm  store(modname+"#"+i, modules[modname]->copies[i]->query(), 0, this_object()); modules[modname]->copies[i]->start(2, this_object());
14179b1997-01-29Per Hedbor  } }
8cc31b1997-10-12Henrik Grubbström (Grubba)  invalidate_cache();
14179b1997-01-29Per Hedbor } // Save all variables in _one_ module.
e351dd1999-11-29Per Hedbor int save_one( RoxenModule o )
14179b1997-01-29Per Hedbor { mapping mod;
10c7e11999-12-28Martin Nilsson  if(!o)
14179b1997-01-29Per Hedbor  {
c5e0961999-10-04Per Hedbor  store("spider#0", variables, 0, this_object());
14179b1997-01-29Per Hedbor  start(2); return 1; }
2c13a81999-11-10Per Hedbor  string q = otomod[ o ]; if( !q ) error("Invalid module");
10c7e11999-12-28Martin Nilsson 
2c13a81999-11-10Per Hedbor  store(q, o->query(), 0, this_object()); invalidate_cache(); o->start(2, this_object()); invalidate_cache(); return 1;
14179b1997-01-29Per Hedbor }
2f79202000-03-27Per Hedbor RoxenModule reload_module( string modname )
5964251999-11-19Per Hedbor {
e351dd1999-11-29Per Hedbor  RoxenModule old_module = find_module( modname );
2f79202000-03-27Per Hedbor  ModuleInfo mi = roxen->find_module( (modname/"#")[0] ); if( !old_module ) return 0;
f569581999-11-23Per Hedbor 
2f79202000-03-27Per Hedbor  save_one( old_module );
1f56521999-11-23Per Hedbor 
9a1d472000-01-12Martin Stjernholm  master()->refresh_inherit( object_program( old_module ) );
2f79202000-03-27Per Hedbor  master()->refresh( object_program( old_module ), 1 ); catch( disable_module( modname, 1 ) );
f569581999-11-23Per Hedbor 
2f79202000-03-27Per Hedbor  RoxenModule nm; if( catch( nm = enable_module( modname ) ) || (nm == 0) ) enable_module( modname, (nm=old_module), mi );
f569581999-11-23Per Hedbor 
2f79202000-03-27Per Hedbor  return nm;
5964251999-11-19Per Hedbor }
7e446c1999-11-24Per Hedbor class ModuleCopies { mapping copies = ([]);
0b7d2b1999-12-22Per Hedbor  mixed `[](mixed q ) { return copies[q]; } mixed `[]=(mixed q,mixed w ) { return copies[q]=w; } mixed _indices() { return(indices(copies)); } mixed _values() { return(values(copies)); }
7e446c1999-11-24Per Hedbor  string _sprintf( ) { return "ModuleCopies()"; } }
beba572000-03-20Martin Stjernholm #ifdef THREADS Thread.Mutex enable_modules_mutex = Thread.Mutex(); #define MODULE_LOCK \ Thread.MutexKey enable_modules_lock = enable_modules_mutex->lock (2) #else #define MODULE_LOCK #endif
9a1d472000-01-12Martin Stjernholm static int enable_module_batch_msgs;
2f79202000-03-27Per Hedbor RoxenModule enable_module( string modname, RoxenModule|void me, ModuleInfo|void moduleinfo )
14179b1997-01-29Per Hedbor {
beba572000-03-20Martin Stjernholm  MODULE_LOCK;
c5e0961999-10-04Per Hedbor  int id;
e351dd1999-11-29Per Hedbor  ModuleCopies module;
c5e0961999-10-04Per Hedbor  int pr; mixed err; int module_type;
e7e6031999-11-05Per Hedbor  if( sscanf(modname, "%s#%d", modname, id ) != 2 )
2f79202000-03-27Per Hedbor  while( modules[ modname ] && modules[ modname ][ id ] )
4f43eb1999-11-05Per Hedbor  id++;
c5e0961999-10-04Per Hedbor 
7f00081998-03-20Per Hedbor  int start_time = gethrtime();
2f79202000-03-27Per Hedbor  mixed err;
25171c1999-11-06Per Hedbor 
2f79202000-03-27Per Hedbor  if( !moduleinfo )
ad683e1998-05-09Henrik Grubbström (Grubba)  {
2f79202000-03-27Per Hedbor  moduleinfo = roxen->find_module( modname ); if (!moduleinfo) { report_warning("Failed to load %s. The module probably " "doesn't exist in the module path.\n", modname); return 0; }
c5e0961999-10-04Per Hedbor  }
9a1d472000-01-12Martin Stjernholm  string descr = moduleinfo->get_name() + (id ? " copy " + (id + 1) : "");
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug(" %-43s... \b", descr );
c5e0961999-10-04Per Hedbor  else
9a1d472000-01-12Martin Stjernholm  report_debug("Enabling " + descr + "\n");
3bbda81997-06-11Henrik Grubbström (Grubba) #endif
c5e0961999-10-04Per Hedbor 
0b7d2b1999-12-22Per Hedbor  module = modules[ modname ];
c5e0961999-10-04Per Hedbor  if(!module)
7e446c1999-11-24Per Hedbor  modules[ modname ] = module = ModuleCopies();
c5e0961999-10-04Per Hedbor 
f569581999-11-23Per Hedbor  if( !me )
c5e0961999-10-04Per Hedbor  {
f569581999-11-23Per Hedbor  if(err = catch(me = moduleinfo->instance(this_object()))) {
c45b2a1999-12-09Martin Stjernholm #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bERROR\n");
0864061999-12-28Martin Stjernholm  if (err != "")
c45b2a1999-12-09Martin Stjernholm #endif
0864061999-12-28Martin Stjernholm  report_error(LOCALE-> error_initializing_module_copy(moduleinfo->get_name(), err != "" && describe_backtrace(err)));
0b7d2b1999-12-22Per Hedbor  return module[id];
f569581999-11-23Per Hedbor  }
c5e0961999-10-04Per Hedbor  }
0b7d2b1999-12-22Per Hedbor  if(module[id] && module[id] != me)
c5e0961999-10-04Per Hedbor  {
c45e3f2000-02-16Per Hedbor  if( module[id]->stop ) module[id]->stop();
f569581999-11-23Per Hedbor // if( err = catch( disable_module( modname+"#"+id ) ) ) // report_error(LOCALE->error_disabling_module(moduleinfo->get_name(), // describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  me->set_configuration( this_object() ); module_type = moduleinfo->type; if (module_type & (MODULE_LOCATION|MODULE_EXTENSION| MODULE_CONFIG|MODULE_FILE_EXTENSION|MODULE_LOGGER| MODULE_URL|MODULE_LAST|MODULE_PROVIDER| MODULE_FILTER|MODULE_PARSER|MODULE_FIRST))
ad683e1998-05-09Henrik Grubbström (Grubba)  {
c5e0961999-10-04Per Hedbor  if(module_type != MODULE_CONFIG)
3b17831998-11-22Per Hedbor  {
4770421999-11-22Henrik Grubbström (Grubba)  if (err = catch { me->defvar("_priority", 5, "Priority", TYPE_INT_LIST, "The priority of the module. 9 is highest and 0 is lowest." " Modules with the same priority can be assumed to be "
10c7e11999-12-28Martin Nilsson  "called in random order",
4770421999-11-22Henrik Grubbström (Grubba)  ({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_priority", "Priorität", "Modul Priorität. 9 höchste, 0 niedrigste." " Module mit gleicher Priorität werden in " "zufälliger Reihenfolge aufgerufen.");
4770421999-11-22Henrik Grubbström (Grubba)  me->deflocaledoc("svenska", "_priority", "Prioritet", "Modulens prioritet, 9 är högst och 0 är" " lägst. Moduler med samma prioritet anropas i " "mer eller mindre slumpmässig ordning."); }) { throw(err); }
3b17831998-11-22Per Hedbor  }
10c7e11999-12-28Martin Nilsson 
c5e0961999-10-04Per Hedbor  if(module_type != MODULE_LOGGER && module_type != MODULE_PROVIDER)
ad683e1998-05-09Henrik Grubbström (Grubba)  {
c5e0961999-10-04Per Hedbor  if(!(module_type & MODULE_PROXY))
14179b1997-01-29Per Hedbor  {
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_sec_group", "user", "Security: Realm", TYPE_STRING, "The realm to use when requesting password from the " "client. Usually used as an informative message to the " "user.");
df6cd11998-10-13Per Hedbor 
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_sec_group", "Sicherheit: Bereich", "Bereichsname, der benutzt werden soll, " "wenn vom Webbrowser ein Passwort angefordert " "werden soll. Wird üblicherweise als informativer " "Hinweis für den Benutzer verwendet.");
df6cd11998-10-13Per Hedbor  me->deflocaledoc("svenska", "_sec_group", "Säkerhet: Grupp", "Gruppnamnet som används när klienten bes" " ange lösenord. I de flesta klienter visas den " " här informationen för användaren i"
3b17831998-11-22Per Hedbor  " lösenordsdialogen.");
df6cd11998-10-13Per Hedbor 
10c7e11999-12-28Martin Nilsson  me->defvar("_seclvl", 0, "Security: Security level", TYPE_INT,
3bf3451998-10-01Peter Bortas  "The modules security level is used to determine if a " " request should be handled by the module." "\n<p><h2>Security level vs Trust level</h2>" " Each module has a configurable <i>security level</i>." " Each request has an assigned trust level. Higher" " <i>trust levels</i> grants access to modules with higher" " <i>security levels</i>." "\n<p><h2>Definitions</h2><ul>" " <li>A requests initial Trust level is infinitely high." " <li> A request will only be handled by a module if its" " <i>trust level</i> is higher or equal to the" " <i>security level</i> of the module." " <li> Each time the request is handled by a module the" " <i>trust level</i> of the module will be set to the" " lower of its <i>trust level</i> and the modules" " <i>security level</i>." " </ul>" "\n<p><h2>Example</h2>" " Modules:<ul>" " <li> User filesystem, <i>security level</i> 1" " <li> Filesystem module, <i>security level</i> 3" " <li> CGI module, <i>security level</i> 2" " </ul>" "\n<p>A request handled by \"User filesystem\" is assigned" " a <i>trust level</i> of one after the <i>security" " level</i> of that module. That request can then not be" " handled by the \"CGI module\" since that module has a" " higher <i>security level</i> than the requests trust" " level." "\n<p>On the other hand, a request handled by the the" " \"Filsystem module\" could later be handled by the" " \"CGI module\".");
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_seclvl", "Sicherheit: Sicherheitsebene", "Die Sicherheitsebene des Moduls wird verwendet, " "wenn ein Request vom Modul behandelt werden soll." "\n<p><h2>Sicherheitsebene vs Vertrauensebene</h2> " "Jedes Modul hat eine konfigurierbare " "<i>Sicherheitsebene</i>." "Jeder Request hat eine zugewiesene Vertrauensebene. " "Höhere <i>Vertrauensebeben</i> erlauben Zugriff zu " "Modulen mir höherer <i>Sicherheitsebene</i>." "\n<p><h2>Definitionen</h2><ul>" " <li>Die ursprüngliche Vertrauensebene eines Requests " " ist unendlich hoch." " <li> Ein Request wird nur von einem Modul behandelt, wenn" " seine <i>Vertrauensebene</i> mindestens so hoch ist," " wie die <i>Sicherheitsebene</i> des Moduls." " <li> Jedes Mal wenn ein Request von einem Modul " " behandelt wird, wird die <i>Vertrauensebene</i>" " des Requests auf den jeweils niedrigeren Wert" " von der <i>Vertrauensebene</i> des Requests und der" " <i>Sicherheitsebene</i> des Moduls, gesetzt." " </ul>" "\n<p><h2>Beispiel</h2>" " Module:<ul>" " <li> User filesystem, <i>Sicherheitsebene</i> 1" " <li> Filesystem module, <i>Sicherheitsebene</i> 3" " <li> CGI module, <i>Sicherheitsebene</i> 2" " </ul>" "\n<p>Ein Request der vom \"User filesystem\" behandelt " "wird bekommt eine <i>Vertrauensebene</i> die der " "<i>Sicherheitsebene</i> des Moduls entspricht. " "Der Request kann dann nicht mehr vom \"CGI module\" " "behandelt werden, da dieses eine höhere " "<i>Sicherheitsebene</i> hat als die Vertrauensebene " "des Requests." "\n<p>Ein Request der vom \"Filsystem module\" behandelt " "wurde kann andererseits später vom \"CGI module\" " "behandelt werden.");
df6cd11998-10-13Per Hedbor  me->deflocaledoc("svenska", "_seclvl", "Säkerhet: Säkerhetsnivå", "Modulens säkerhetsnivå används för att avgöra om " " en specifik request ska få hanteras av modulen. " "\n<p><h2>Säkerhetsnivå och pålitlighetsnivå</h2>" " Varje modul har en konfigurerbar " "<i>säkerhtesnivå</i>. " "Varje request har en <i>pålitlighetsnivå</i>.<p>" "Högre <i>pålitlighetsnivåer</i> ger " " requesten tillgång till moduler med högre " "<i>säkerhetsnivå</i>. <p>\n" "\n<p><h2>Defenitioner</h2><ul>" " <li>En requests initialpålitlighetsnivå är " " oändligt hög." " <li> En request hanteras bara av moduler om " "dess <i>pålitlighetsnivå</i> är högre eller " " lika hög som modulens <i>säkerhetsnivå</i>" " <li> Varje gång en request hanteras av en" " modul så sätts dess <i>pålitlighetsnivå</i> " "till modulens <i>säkerhetsnivå</i> om " " modulen har en <i>säkerhetsnivå</i> som är " "skiljd from noll. " " </ul>" "\n<p><h2>Ett exempel</h2>" " Moduler:<ul>" " <li> Användarfilsystem, <i>säkerhetsnivå</i> 1" " <li> Filesystem, <i>säkerhetsnivå</i> 3" " <li> CGI modul, <i>säkerhetsnivå</i> 2" " </ul>" "\n<p>En request hanterad av " " <i>Användarfilsystemet</i> får ett " "som <i>pålitlighetsnivå</i>. Den här" " requesten kan därför inte skickas vidare " "till <i>CGI modulen</i> eftersom den har" " en <i>säkerhetsnivå</i> som är högre än" " requestens <i>pålitlighetsnivå</i>.<p>" " Å andra sidan så kan en request som " " hanteras av <i>Filsystem</i> modulen " " skickas vidare till <i>CGI modulen</i>.");
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_seclevels", "", "Security: Patterns", TYPE_TEXT_FIELD, "This is the 'security level=value' list.<br>" "Each security level can be any or more from this list:" "<hr noshade>" "allow ip=<i>IP</i>/<i>bits</i><br>" "allow ip=<i>IP</i>:<i>mask</i><br>" "allow ip=<i>pattern</i><br>" "allow user=<i>username</i>,...<br>" "deny ip=<i>IP</i>/<i>bits</i><br>" "deny ip=<i>IP</i>:<i>mask</i><br>" "deny ip=<i>pattern</i><br>" "<hr noshade>" "In patterns: * matches one or more characters, " "and ? matches one character.<p>" "In username: 'any' stands for any valid account " "(from .htaccess"
0026281999-06-07Martin Stjernholm  " or an auth module. The default (used when _no_ "
ad683e1998-05-09Henrik Grubbström (Grubba)  "entries are present) is 'allow ip=*', allowing" " everyone to access the module");
df6cd11998-10-13Per Hedbor 
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_seclevels", "Sicherheit: Muster", "Dies ist die Liste der Sicherheitsmuster.<p>" "Jede Sicherheitsebene kann aus einem oder mehr " "der folgenden Einträgen bestehen: " "<hr noshade>" "allow ip=<i>IP-Adresse</i>/<i>Bits</i><br>" "allow ip=<i>IP-Adresse</i>:<i>Netzmaske</i><br>" "allow ip=<i>Muster</i><br>" "allow user=<i>Benutzername</i>,...<br>" "deny ip=<i>IP-Adresse</i>/<i>Bits</i><br>" "deny ip=<i>IP-nummer</i>:<i>Netzmaske</i><br>" "deny ip=<i>Muster</i><br>" "<hr noshade>" "Bei den Mustern trifft '*' auf ein oder " "mehrere Zeichen zu, '?' auf genau ein " "Zeichen.<p> " "Bei den Benutzernamen steht 'any' für jeden " "gültigen Benutzernamen " "(aus einer .htaccess-Datei oder jedem anderen " "Auth-Modul) Der Standard-Wert (wenn keine Eingaben " "gemacht wurden), ist 'allow ip=*', d.h. jeder " "darf auf das Modul zugreifen.");
10c7e11999-12-28Martin Nilsson  me->deflocaledoc("svenska", "_seclevels",
df6cd11998-10-13Per Hedbor  "Säkerhet: Behörighetsregler", "Det här är en lista av behörighetsregler.<p>" "Varje behörighetsregler måste följa någon av de " " här mönstren: " "<hr noshade>" "allow ip=<i>IP-nummer</i>/<i>antal nätmaskbittar</i><br>" "allow ip=<i>IP-nummer</i>:<i>nätmask</i><br>" "allow ip=<i>globmönster</i><br>" "allow user=<i>användarnamn</i>,...<br>" "deny ip=<i>IP-nummer</i>/<i>antal nätmaskbittar</i><br>" "deny ip=<i>IP-nummer</i>:<i>nätmask</i><br>" "deny ip=<i>globmönster</i><br>" "<hr noshade>" "I globmänster betyer '*' ett eller flera " "godtyckliga tecken, och '?' betyder exekt " "ett godtyckligt tecken.<p> " "Användnamnet 'any' kan användas för att ange " "att vilken giltig användare som helst ska " " kunna få använda modulen.");
ad683e1998-05-09Henrik Grubbström (Grubba)  } else { me->definvisvar("_seclvl", -10, TYPE_INT); /* A very low one */
a8f1b32000-01-31Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_sec_group", "user", "Proxy Security: Realm", TYPE_STRING, "The realm to use when requesting password from the " "client. Usually used as an informative message to the " "user.");
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_sec_group", "Sicherheit: Bereich", "Bereichsname, der benutzt werden soll, " "wenn vom Webbrowser ein Passwort angefordert " "werden soll. Wird üblicherweise als informativer " "Hinweis für den Benutzer verwendet.");
df6cd11998-10-13Per Hedbor  me->deflocaledoc("svenska", "_sec_group", "Säkerhet: Grupp", "Gruppnamnet som används när klienten bes" " ange lösenord. I de flesta klienter visas den " " här informationen för användaren i" "lösenordsdialogen.");
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_seclevels", "", "Proxy security: Patterns", TYPE_TEXT_FIELD, "This is the 'security level=value' list.<br>" "Each security level can be any or more from " "this list:<br>" "<hr noshade>" "allow ip=pattern<br>" "allow user=username,...<br>" "deny ip=pattern<br>" "<hr noshade>" "In patterns: * is on or more characters, ? is one " " character.<p>" "In username: 'any' stands for any valid account" " (from .htaccess"
0026281999-06-07Martin Stjernholm  " or an auth module. The default is 'deny ip=*'");
df6cd11998-10-13Per Hedbor 
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_seclevels", "Sicherheit: Muster", "Dies ist die Liste der Sicherheitsmuster.<p>" "Jede Sicherheitsebene kann aus einem oder mehr " "der folgenden Einträgen bestehen: " "<hr noshade>" "allow ip=<i>IP-Adresse</i>/<i>Bits</i><br>" "allow ip=<i>IP-Adresse</i>:<i>Netzmaske</i><br>" "allow ip=<i>Muster</i><br>" "allow user=<i>Benutzername</i>,...<br>" "deny ip=<i>IP-Adresse</i>/<i>Bits</i><br>" "deny ip=<i>IP-nummer</i>:<i>Netzmaske</i><br>" "deny ip=<i>Muster</i><br>" "<hr noshade>" "Bei den Mustern trifft '*' auf ein oder " "mehrere Zeichen zu, '?' auf genau ein " "Zeichen.<p> " "Bei den Benutzernamen steht 'any' für jeden " "gültigen Benutzernamen " "(aus einer .htaccess-Datei oder jedem anderen " "Auth-Modul) Der Standard-Wert (wenn keine Eingaben " "gemacht wurden), ist 'allow ip=*', d.h. jeder " "darf auf das Modul zugreifen.");
10c7e11999-12-28Martin Nilsson  me->deflocaledoc("svenska", "_seclevels",
df6cd11998-10-13Per Hedbor  "Säkerhet: Behörighetsregler", "Det här är en lista av behörighetsregler.<p>" "Varje behörighetsregler måste följa någon av de " " här mönstren: " "<hr noshade>" "allow ip=<i>IP-nummer</i>/<i>antal nätmaskbittar</i><br>" "allow ip=<i>IP-nummer</i>:<i>nätmask</i><br>" "allow ip=<i>globmönster</i><br>" "allow user=<i>användarnamn</i>,...<br>" "deny ip=<i>IP-nummer</i>/<i>antal nätmaskbittar</i><br>" "deny ip=<i>IP-nummer</i>:<i>nätmask</i><br>" "deny ip=<i>globmönster</i><br>" "<hr noshade>" "I globmänster betyer '*' ett eller flera " "godtyckliga tecken, och '?' betyder exekt " "ett godtyckligt tecken.<p> " "Användnamnet 'any' kan användas för att ange " "att vilken giltig användare som helst ska " " kunna få använda modulen.");
14179b1997-01-29Per Hedbor  }
3bbda81997-06-11Henrik Grubbström (Grubba)  }
ad683e1998-05-09Henrik Grubbström (Grubba)  } else { me->defvar("_priority", 0, "", TYPE_INT, "", 0, 1); }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_comment", "", " Comment", TYPE_TEXT_FIELD|VAR_MORE, "An optional comment. This has no effect on the module, it " "is only a text field for comments that the administrator " "might have (why the module are here, etc.)");
14179b1997-01-29Per Hedbor 
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_comment", "Kommentar", "Ein Kommentar, der keinen technischen Einfluss " "auf das Modul hat, sondern lediglich ein Textfeld " "für Kommentare seitens des Administrators ist.");
10c7e11999-12-28Martin Nilsson  me->deflocaledoc("svenska", "_comment",
df6cd11998-10-13Per Hedbor  "Kommentar", "En kommentar. Den här kommentaren påverkar inte " " funktionaliteten hos modulen på något sätt, den " " syns bara i konfigurationsinterfacet.");
ad683e1998-05-09Henrik Grubbström (Grubba)  me->defvar("_name", "", " Module name", TYPE_STRING|VAR_MORE,
a0fbcc2000-04-05Martin Stjernholm  "An optional name. You can set it to something to remind you what "
ad683e1998-05-09Henrik Grubbström (Grubba)  "the module really does.");
14179b1997-01-29Per Hedbor 
e6f83d2000-03-06Peter Bortas  me->deflocaledoc("deutsch", "_name", "Modul-Name", "Modul-Name. Hier kann ein beliebiger Wert eingetragen " "werden, um die Funktionsweise des Moduls zu beschreiben.");
df6cd11998-10-13Per Hedbor  me->deflocaledoc("svenska", "_name", "Namn", "Modulens namn. Om den här variablen är satt så " "används dess värde istället för modulens riktiga namn " "i konfigurationsinterfacet.");
a0fbcc2000-04-05Martin Stjernholm  mapping(string:mixed) stored_vars = retrieve(modname + "#" + id, this_object()); int has_stored_vars = sizeof (stored_vars); // A little ugly, but it suffices. me->setvars(stored_vars);
33e6351998-02-28Martin Stjernholm 
0b7d2b1999-12-22Per Hedbor  module[ id ] = me;
37c1b31999-10-12Per Hedbor  otomod[ me ] = modname+"#"+id;
10c7e11999-12-28Martin Nilsson 
ad683e1998-05-09Henrik Grubbström (Grubba)  mixed err;
c5e0961999-10-04Per Hedbor  if((me->start) && (err = catch( me->start(0, this_object()) ) ) ) { #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bERROR\n");
c5e0961999-10-04Per Hedbor #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->
c5e0961999-10-04Per Hedbor  error_initializing_module_copy(moduleinfo->get_name(),
001ae71998-10-11Henrik Grubbström (Grubba)  describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba) 
c5e0961999-10-04Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  /* Clean up some broken references to this module. */ m_delete(otomod, me);
0b7d2b1999-12-22Per Hedbor  m_delete(module->copies, id);
ad683e1998-05-09Henrik Grubbström (Grubba)  destruct(me); return 0; }
5ffa542000-02-16Per Hedbor  if( inited && me->ready_to_receive_requests )
c2fdff2000-03-21Martin Stjernholm  if( mixed q = catch( me->ready_to_receive_requests( this_object() ) ) ) { #ifdef MODULE_DEBUG if (enable_module_batch_msgs) report_debug("\bERROR\n"); #endif report_error( "While calling ready_to_receive_requests:\n"+ describe_backtrace( q ) ); }
10c7e11999-12-28Martin Nilsson  if (err = catch(pr = me->query("_priority")))
c5e0961999-10-04Per Hedbor  {
c45b2a1999-12-09Martin Stjernholm #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bERROR\n");
c45b2a1999-12-09Martin Stjernholm #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->
c5e0961999-10-04Per Hedbor  error_initializing_module_copy(moduleinfo->get_name(),
001ae71998-10-11Henrik Grubbström (Grubba)  describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  pr = 3; } api_module_cache |= me->api_functions();
10c7e11999-12-28Martin Nilsson  if(module_type & MODULE_EXTENSION)
c5e0961999-10-04Per Hedbor  { report_error( moduleinfo->get_name()+ " is an MODULE_EXTENSION, that type is no " "longer available.\nPlease notify the modules writer.\n" "Suitable replacement types include MODULE_FIRST and " " MODULE_LAST\n"); }
ad683e1998-05-09Henrik Grubbström (Grubba) 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_FILE_EXTENSION)
ad683e1998-05-09Henrik Grubbström (Grubba)  if (err = catch { array arr = me->query_file_extensions();
10c7e11999-12-28Martin Nilsson  if (arrayp(arr))
c5e0961999-10-04Per Hedbor  {
ad683e1998-05-09Henrik Grubbström (Grubba)  string foo; foreach( me->query_file_extensions(), foo )
10c7e11999-12-28Martin Nilsson  if(pri[pr]->file_extension_modules[foo] )
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->file_extension_modules[foo]+=({me}); else pri[pr]->file_extension_modules[foo]=({me}); }
c45b2a1999-12-09Martin Stjernholm  }) { #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bERROR\n");
c45b2a1999-12-09Martin Stjernholm #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->
c5e0961999-10-04Per Hedbor  error_initializing_module_copy(moduleinfo->get_name(),
001ae71998-10-11Henrik Grubbström (Grubba)  describe_backtrace(err)));
c45b2a1999-12-09Martin Stjernholm  }
14179b1997-01-29Per Hedbor 
10c7e11999-12-28Martin Nilsson  if(module_type & MODULE_PROVIDER) if (err = catch
c5e0961999-10-04Per Hedbor  {
ad683e1998-05-09Henrik Grubbström (Grubba)  mixed provs = me->query_provides(); if(stringp(provs)) provs = (< provs >); if(arrayp(provs)) provs = mkmultiset(provs); if (multisetp(provs)) { pri[pr]->provider_modules [ me ] = provs;
3bbda81997-06-11Henrik Grubbström (Grubba)  }
c45b2a1999-12-09Martin Stjernholm  }) { #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bERROR\n");
c45b2a1999-12-09Martin Stjernholm #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->
c5e0961999-10-04Per Hedbor  error_initializing_module_copy(moduleinfo->get_name(), describe_backtrace(err)));
c45b2a1999-12-09Martin Stjernholm  }
10c7e11999-12-28Martin Nilsson 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_TYPES)
ad683e1998-05-09Henrik Grubbström (Grubba)  { types_module = me; types_fun = me->type_from_extension; }
10c7e11999-12-28Martin Nilsson 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_PARSER) add_parse_module( me );
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_AUTH)
ad683e1998-05-09Henrik Grubbström (Grubba)  { auth_module = me; auth_fun = me->auth; }
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_DIRECTORIES)
ad683e1998-05-09Henrik Grubbström (Grubba)  dir_module = me;
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_LOCATION)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->location_modules += ({ me });
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_LOGGER)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->logger_modules += ({ me });
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_URL)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->url_modules += ({ me });
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_LAST)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->last_modules += ({ me });
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_FILTER)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->filter_modules += ({ me });
14179b1997-01-29Per Hedbor 
10c7e11999-12-28Martin Nilsson  if(module_type & MODULE_FIRST)
ad683e1998-05-09Henrik Grubbström (Grubba)  pri[pr]->first_modules += ({ me });
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(!enabled_modules[ modname+"#"+id ])
ad683e1998-05-09Henrik Grubbström (Grubba)  { enabled_modules[modname+"#"+id] = 1;
c5e0961999-10-04Per Hedbor  store( "EnabledModules", enabled_modules, 1, this_object());
ad683e1998-05-09Henrik Grubbström (Grubba)  }
a0fbcc2000-04-05Martin Stjernholm  if (!has_stored_vars) store (modname + "#" + id, me->query(), 0, this_object());
ad683e1998-05-09Henrik Grubbström (Grubba)  invalidate_cache();
c45b2a1999-12-09Martin Stjernholm #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\bOK %6.1fms\n", (gethrtime()-start_time)/1000.0);
c45b2a1999-12-09Martin Stjernholm #endif
c45e3f2000-02-16Per Hedbor  if( me->no_delayed_load ) set( "no_delayed_load", 1 );
ad683e1998-05-09Henrik Grubbström (Grubba)  return me;
14179b1997-01-29Per Hedbor }
a6ef1f2000-03-28Johan Sundström // Called from the administration interface.
199d031999-09-05Francesco Chemolli string check_variable(string name, mixed value)
14179b1997-01-29Per Hedbor { switch(name) { case "MyWorldLocation": if(strlen(value)<7 || value[-1] != '/' || !(sscanf(value,"%*s://%*s/")==2))
001ae71998-10-11Henrik Grubbström (Grubba)  return LOCALE->url_format();
4f4bc11998-02-04Per Hedbor  return 0;
199d031999-09-05Francesco Chemolli  case "throttle": if (value) { THROTTLING_DEBUG("configuration: Starting throttler up"); throttler=.throttler(); throttler->throttle(query("throttle_fill_rate"), query("throttle_bucket_depth"), query("throttle_min_grant"), query("throttle_max_grant")); } else { THROTTLING_DEBUG("configuration: Stopping throttler"); destruct(throttler); throttler=0; } return 0; case "throttle_fill_rate": case "throttle_bucket_depth": case "throttle_min_grant": case "throttle_max_grant": THROTTLING_DEBUG("configuration: setting throttling parameter: "+ name+"="+value); throttler->throttle(query("throttle_fill_rate"), query("throttle_bucket_depth"), query("throttle_min_grant"), query("throttle_max_grant")); return 0;
14179b1997-01-29Per Hedbor  } }
2f79202000-03-27Per Hedbor int disable_module( string modname, int|void nodest )
14179b1997-01-29Per Hedbor {
beba572000-03-20Martin Stjernholm  MODULE_LOCK;
e351dd1999-11-29Per Hedbor  RoxenModule me;
c5e0961999-10-04Per Hedbor  int id, pr;
14179b1997-01-29Per Hedbor  sscanf(modname, "%s#%d", modname, id );
e351dd1999-11-29Per Hedbor  ModuleInfo moduleinfo = roxen->find_module( modname );
c5e0961999-10-04Per Hedbor  mapping module = modules[ modname ];
9a1d472000-01-12Martin Stjernholm  string descr = moduleinfo->get_name() + (id ? " copy " + (id + 1) : "");
14179b1997-01-29Per Hedbor 
10c7e11999-12-28Martin Nilsson  if(!module)
14179b1997-01-29Per Hedbor  {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->disable_nonexistant_module(modname));
14179b1997-01-29Per Hedbor  return 0; }
0b7d2b1999-12-22Per Hedbor  me = module[id];
c5e0961999-10-04Per Hedbor  m_delete(module->copies, id);
10c7e11999-12-28Martin Nilsson 
c5e0961999-10-04Per Hedbor  if(!sizeof(module->copies)) m_delete( modules, modname );
14179b1997-01-29Per Hedbor 
8cc31b1997-10-12Henrik Grubbström (Grubba)  invalidate_cache();
14179b1997-01-29Per Hedbor  if(!me) {
9a1d472000-01-12Martin Stjernholm  report_error(LOCALE->disable_module_failed(descr));
14179b1997-01-29Per Hedbor  return 0; }
9a1d472000-01-12Martin Stjernholm  if(me->stop) if (mixed err = catch (me->stop())) report_error (LOCALE->error_disabling_module (descr, describe_backtrace (err)));
14179b1997-01-29Per Hedbor  #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  report_debug("Disabling "+descr+"\n");
14179b1997-01-29Per Hedbor #endif
c5e0961999-10-04Per Hedbor  if(moduleinfo->type & MODULE_FILE_EXTENSION)
14179b1997-01-29Per Hedbor  { string foo;
d54d061999-06-10Martin Stjernholm  for(pr=0; pr<10; pr++) foreach( indices (pri[pr]->file_extension_modules), foo ) pri[pr]->file_extension_modules[foo]-=({me});
14179b1997-01-29Per Hedbor  }
c5e0961999-10-04Per Hedbor  if(moduleinfo->type & MODULE_PROVIDER) {
ae32d01998-03-23David Hedbor  for(pr=0; pr<10; pr++) m_delete(pri[pr]->provider_modules, me); }
10c7e11999-12-28Martin Nilsson 
c5e0961999-10-04Per Hedbor  if(moduleinfo->type & MODULE_TYPES)
14179b1997-01-29Per Hedbor  { types_module = 0; types_fun = 0; }
c5e0961999-10-04Per Hedbor  if(moduleinfo->type & MODULE_PARSER)
b796b51998-11-18Per Hedbor  remove_parse_module( me );
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_AUTH )
14179b1997-01-29Per Hedbor  { auth_module = 0; auth_fun = 0; }
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_DIRECTORIES )
14179b1997-01-29Per Hedbor  dir_module = 0;
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_LOCATION )
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->location_modules -= ({ me });
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_URL )
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->url_modules -= ({ me });
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_LAST )
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->last_modules -= ({ me });
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_FILTER )
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->filter_modules -= ({ me });
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_FIRST ) {
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->first_modules -= ({ me });
f128901997-08-15Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if( moduleinfo->type & MODULE_LOGGER )
14179b1997-01-29Per Hedbor  for(pr=0; pr<10; pr++) pri[pr]->logger_modules -= ({ me });
c5e0961999-10-04Per Hedbor  if( enabled_modules[modname+"#"+id] )
14179b1997-01-29Per Hedbor  { m_delete( enabled_modules, modname + "#" + id );
c5e0961999-10-04Per Hedbor  store( "EnabledModules",enabled_modules, 1, this_object());
14179b1997-01-29Per Hedbor  }
2f79202000-03-27Per Hedbor  if(!nodest) destruct(me);
14179b1997-01-29Per Hedbor  return 1; }
e351dd1999-11-29Per Hedbor RoxenModule|string find_module(string name)
14179b1997-01-29Per Hedbor { int id; sscanf(name, "%s#%d", name, id); if(modules[name])
c5e0961999-10-04Per Hedbor  return modules[name]->copies[id];
14179b1997-01-29Per Hedbor  return 0; }
f5a2741999-10-18Per Hedbor multiset forcibly_added = (<>); int add_modules( array(string) mods, int|void now )
14179b1997-01-29Per Hedbor {
ba18d71999-11-27Per Hedbor #ifdef MODULE_DEBUG
c5e0961999-10-04Per Hedbor  int wr;
ba18d71999-11-27Per Hedbor #endif
c5e0961999-10-04Per Hedbor  foreach (mods, string mod)
8f061b1999-11-19Per Hedbor  { sscanf( mod, "%s#", mod );
10c7e11999-12-28Martin Nilsson  if( ((now && !modules[ mod ]) ||
0ce25d1999-11-15Per Hedbor  !enabled_modules[ mod+"#0" ] ) && !forcibly_added[ mod+"#0" ])
14179b1997-01-29Per Hedbor  {
ba18d71999-11-27Per Hedbor #ifdef MODULE_DEBUG
c5e0961999-10-04Per Hedbor  if( !wr++ )
9a1d472000-01-12Martin Stjernholm  if (enable_module_batch_msgs) report_debug("\b[ adding req module" + (sizeof (mods) > 1 ? "s" : "") + "\n"); else report_debug("Adding required module" + (sizeof (mods) > 1 ? "s" : "") + "\n");
14179b1997-01-29Per Hedbor #endif
9a1d472000-01-12Martin Stjernholm  forcibly_added[ mod+"#0" ] = 1; enable_module( mod+"#0" );
14179b1997-01-29Per Hedbor  }
8f061b1999-11-19Per Hedbor  }
ba18d71999-11-27Per Hedbor #ifdef MODULE_DEBUG
9a1d472000-01-12Martin Stjernholm  if( wr && enable_module_batch_msgs )
ed8d261999-12-30Martin Stjernholm  report_debug("] \b");
c79b261998-02-05Johan Schön #endif
14179b1997-01-29Per Hedbor }
279a0c1997-11-26Henrik Grubbström (Grubba) // BEGIN SQL
14179b1997-01-29Per Hedbor 
279a0c1997-11-26Henrik Grubbström (Grubba) mapping(string:string) sql_urls = ([]);
ed93131998-07-09Johan Schön mapping sql_cache = ([]);
e351dd1999-11-29Per Hedbor Sql.sql sql_cache_get(string what)
ed93131998-07-09Johan Schön { #ifdef THREADS if(sql_cache[what] && sql_cache[what][this_thread()]) return sql_cache[what][this_thread()]; if(!sql_cache[what]) sql_cache[what] = ([ this_thread():Sql.sql( what ) ]); else sql_cache[what][ this_thread() ] = Sql.sql( what ); return sql_cache[what][ this_thread() ]; #else /* !THREADS */ if(!sql_cache[what]) sql_cache[what] = Sql.sql( what ); return sql_cache[what]; #endif }
e351dd1999-11-29Per Hedbor Sql.sql sql_connect(string db)
279a0c1997-11-26Henrik Grubbström (Grubba) {
c5e0961999-10-04Per Hedbor  if (sql_urls[db]) return sql_cache_get(sql_urls[db]); else return sql_cache_get(db);
279a0c1997-11-26Henrik Grubbström (Grubba) } // END SQL
14179b1997-01-29Per Hedbor 
1e5ee81997-08-21Per Hedbor // This is the most likely URL for a virtual server.
14179b1997-01-29Per Hedbor private string get_my_url() { string s;
c79b261998-02-05Johan Schön #if efun(gethostname)
14179b1997-01-29Per Hedbor  s = (gethostname()/".")[0] + "." + query("Domain"); s -= "\n";
c79b261998-02-05Johan Schön #else s = "localhost"; #endif
14179b1997-01-29Per Hedbor  return "http://" + s + "/"; }
5ffa542000-02-16Per Hedbor array after_init_hooks = ({}); mixed add_init_hook( mixed what ) { if( inited ) call_out( what, 0, this_object() ); else after_init_hooks |= ({ what }); }
0f28da1997-08-13Per Hedbor void enable_all_modules()
14179b1997-01-29Per Hedbor {
beba572000-03-20Martin Stjernholm  MODULE_LOCK;
c45e3f2000-02-16Per Hedbor  int q = query( "no_delayed_load" ); set( "no_delayed_load", 0 ); low_init( ); if( q != query( "no_delayed_load" ) ) save_one( 0 );
5ffa542000-02-16Per Hedbor }
c45e3f2000-02-16Per Hedbor void low_init()
5ffa542000-02-16Per Hedbor { if( inited ) return; // already done
8516a71999-12-22Per Hedbor 
24c06c2000-02-16Per Hedbor  int start_time = gethrtime(); report_debug("\nEnabling all modules for "+query_name()+"... \n");
1d7d6d2000-02-16Per Hedbor  add_parse_module( (object)this_object() ); enabled_modules = retrieve("EnabledModules", this_object());
6958011999-12-28Martin Stjernholm  object ec = roxenloader.LowErrorContainer(); roxenloader.push_compile_error_handler( ec );
c5e0961999-10-04Per Hedbor  array modules_to_process = indices( enabled_modules );
14179b1997-01-29Per Hedbor  string tmp_string;
44f2431999-06-07Martin Stjernholm  parse_log_formats(); init_log_file();
0f28da1997-08-13Per Hedbor  // Always enable the user database module first. if(search(modules_to_process, "userdb#0")>-1) modules_to_process = (({"userdb#0"})+(modules_to_process-({"userdb#0"}))); array err;
f5a2741999-10-18Per Hedbor  forcibly_added = (<>);
9a1d472000-01-12Martin Stjernholm  enable_module_batch_msgs = 1;
0f28da1997-08-13Per Hedbor  foreach( modules_to_process, tmp_string )
f5a2741999-10-18Per Hedbor  {
6958011999-12-28Martin Stjernholm  if( !forcibly_added[ tmp_string ] )
f5a2741999-10-18Per Hedbor  if(err = catch( enable_module( tmp_string )))
10c7e11999-12-28Martin Nilsson  report_error(LOCALE->enable_module_failed(tmp_string,
f5a2741999-10-18Per Hedbor  describe_backtrace(err))); }
9a1d472000-01-12Martin Stjernholm  enable_module_batch_msgs = 0;
6958011999-12-28Martin Stjernholm  roxenloader.pop_compile_error_handler(); if( strlen( ec->get() ) ) report_error( "While enabling modules in "+name+":\n"+ec->get() );
17d6d12000-03-30Per Hedbor  if( strlen( ec->get_warnings() ) ) report_warning( "While enabling modules in "+name+":\n"+ec->get_warnings());
5ffa542000-02-16Per Hedbor  foreach( ({this_object()})+indices( otomod ), object mod ) if( mod->ready_to_receive_requests ) if( mixed q = catch( mod->ready_to_receive_requests( this_object() ) ) )
c2fdff2000-03-21Martin Stjernholm  report_error( "While calling ready_to_receive_requests in "+
5ffa542000-02-16Per Hedbor  otomod[mod]+":\n"+ describe_backtrace( q ) ); foreach( after_init_hooks, function q ) if( mixed w = catch( q ) )
c2fdff2000-03-21Martin Stjernholm  report_error( "While calling after_init_hook %O:\n%s",
5ffa542000-02-16Per Hedbor  q, describe_backtrace( w ) ); after_init_hooks = ({}); inited = 1;
10c7e11999-12-28Martin Nilsson  report_notice("All modules for %s enabled in %3.1f seconds\n\n",
07c9921999-11-23Per Hedbor  query_name(),(gethrtime()-start_time)/1000000.0);
0f28da1997-08-13Per Hedbor } void create(string config) {
14179b1997-01-29Per Hedbor  name=config;
001ae71998-10-11Henrik Grubbström (Grubba) 
9b9f701997-08-12Per Hedbor  defvar("comment", "", "Virtual server comment", TYPE_TEXT_FIELD|VAR_MORE,
a6ef1f2000-03-28Johan Sundström  "This text will be visible in the administration interface, it "
14179b1997-01-29Per Hedbor  " can be quite useful to use as a memory helper.");
b796b51998-11-18Per Hedbor 
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "comment", "Kommentar", "Ein Kommentar, der im Konfigurations-Interface " "sichtbar ist und als Dokumentation nützlich ist.");
b796b51998-11-18Per Hedbor  deflocaledoc("svenska", "comment", "Kommentar", "En kommentar som syns i konfigurationsinterfacet");
9b9f701997-08-12Per Hedbor  defvar("name", "", "Virtual server name", TYPE_STRING|VAR_MORE,
14179b1997-01-29Per Hedbor  "This is the name that will be used in the configuration " "interface. If this is left empty, the actual name of the " "virtual server will be used");
c5e0961999-10-04Per Hedbor 
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "name", "Servername", #"Dies ist der Name, der im Konfigurations-Interface für den virtuellen Server benutzt wird. Wird dieses Feld leer gelassen, wird der eigentliche Name des virtuellen Servers benutzt.");
b796b51998-11-18Per Hedbor  deflocaledoc("svenska", "name", "Serverns namn", #"Det här är namnet som kommer att synas i konfigurationsgränssnittet. Om du lämnar det här fältet tomt kommer serverns ursprungliga namn (det du skrev in när du skapade servern) att användas.");
10c7e11999-12-28Martin Nilsson  defvar("LogFormat",
14179b1997-01-29Per Hedbor  "404: $host $referer - [$cern_date] \"$method $resource $protocol\" 404 -\n"
2d4d4f1997-08-01Fredrik Noring  "500: $host $referer ERROR [$cern_date] \"$method $resource $protocol\" 500 -\n"
14179b1997-01-29Per Hedbor  "*: $host - - [$cern_date] \"$method $resource $protocol\" $response $length" ,
10c7e11999-12-28Martin Nilsson  "Logging: Format",
9b9f701997-08-12Per Hedbor  TYPE_TEXT_FIELD|VAR_MORE,
a8f1b32000-01-31Per Hedbor 
14179b1997-01-29Per Hedbor  "What format to use for logging. The syntax is:\n" "<pre>" "response-code or *: Log format for that response acode\n\n" "Log format is normal characters, or one or more of the " "variables below:\n" "\n" "\\n \\t \\r -- As in C, newline, tab and linefeed\n" "$char(int) -- Insert the (1 byte) character specified by the integer.\n" "$wchar(int) -- Insert the (2 byte) word specified by the integer.\n" "$int(int) -- Insert the (4 byte) word specified by the integer.\n" "$^ -- Supress newline at the end of the logentry\n" "$host -- The remote host name, or ip number.\n" "$ip_number -- The remote ip number.\n" "$bin-ip_number -- The remote host id as a binary integer number.\n" "\n" "$cern_date -- Cern Common Log file format date.\n" "$bin-date -- Time, but as an 32 bit iteger in network byteorder\n" "\n" "$method -- Request method\n" "$resource -- Resource identifier\n"
dfb4ec1999-05-20Francesco Chemolli  "$full_resource -- Full requested resource, including any query fields\n"
14179b1997-01-29Per Hedbor  "$protocol -- The protocol used (normally HTTP/1.0)\n" "$response -- The response code sent\n" "$bin-response -- The response code sent as a binary short number\n" "$length -- The length of the data section of the reply\n" "$bin-length -- Same, but as an 32 bit iteger in network byteorder\n"
0bf5a11998-04-03Henrik Grubbström (Grubba)  "$request-time -- The time the request took (seconds)\n"
14179b1997-01-29Per Hedbor  "$referer -- the header 'referer' from the request, or '-'.\n" "$user_agent -- the header 'User-Agent' from the request, or '-'.\n\n" "$user -- the name of the auth user used, if any\n" "$user_id -- A unique user ID, if cookies are supported,\n" " by the client, otherwise '0'\n"
c5e0961999-10-04Per Hedbor  "</pre>", 0, lambda(){ return !query("Log");});
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "LogFormat", "Logging: Loggingformat", #"Welches Format soll für die Logfiles benutzt werden. <pre> Antwort-Code oder *: Loggingformat für diesen Antwort-Code (z.B 404) Das Loggingformat ist normaler Text, in den folgende Variabeln eingesetzt werden können. \\n \\t \\r -- Newline, Tab oder Linefeed-Zeichen (wie in C) $char(int) -- Fügt das 8Bit-Zeichen ein, das dem Integerwert entspricht. $wchar(int) -- Fügt das 16Bit-Zeichen ein, das dem Integerwert entspricht. $int(int) -- Fügt das 32Bit-Word ein, das dem Integerwert entspricht. $^ -- Unterdrückt das Newline-Zeichen am Ende des Eintrages. $host -- Hostname oder IP-Adresse des Webbrowsers. $ip_number -- IP-Adresse des Webbrowsers. $bin-ip_number -- IP-Adresse des Webbrowsers in 32Bit-Dezimaldarstellung. $cern_date -- Uhrzeit und Datum im CERN-Format. $bin-date -- Zeit als 32Bit-Integer-Darstellung (Sekunden seit 1.1.1970). $method -- Anfrage-Methode (GET, POST, usw.) $resource -- Angeforderte Datei. $protocol -- Verwendetes Protokoll (normalerweise HTTP/1.0 oder HTTP/1.1) $response -- Der verschichte Antwort-Code $bin-response -- Der verschickte Antwort-Code in 32Bit-Dezimaldarstellung $length -- Die Größe der verschickten Daten $bin-length -- Die Größe der verschickten Daten in 32Bit-Dezimaldarstellung $request-time -- Verstrichene Zeit in Sekunden, die die Anfrage benötigt hat $referer -- Die 'referer'-Information aus der Anfrage, oder '-' $user_agent -- Die 'user-agent'-Information aus der Anfrage, oder '-' $user -- Der Name des angemeldeten Benutzers, sofern vorhanden $user_id -- Die eindeutige Benutzerkennung, sofern Cookies vom Browser unterstützt wurden, ansonsten '0'. </pre>");
b796b51998-11-18Per Hedbor  deflocaledoc("svenska", "LogFormat", "Loggning: Loggningsformat", #"Vilket format som ska användas för att logga <pre>
10c7e11999-12-28Martin Nilsson svarskod eller *: Loggformat för svarskoden (eller alla koder som inte
b796b51998-11-18Per Hedbor  har något annat format specifierat om du använder '*') loggformatet är normala tecken, och en eller flera av koderna nedan. \\n \\t \\r -- Precis som i C, ny rad, tab och carriage return $char(int) -- Stoppa in det tecken vars teckenkod är det angivna nummret.
10c7e11999-12-28Martin Nilsson $wchar(int) -- Stoppa in det tvåocktetstecken vars teckenkod är det
b796b51998-11-18Per Hedbor  angivna nummret.
10c7e11999-12-28Martin Nilsson $int(int) -- Stoppa in det fyraocktetstecken vars teckenkod är det
b796b51998-11-18Per Hedbor  angivna nummret. $^ -- Stoppa <b>inte</b> in en vagnretur på slutet av varje loggrad $host -- DNS namnet för datorn som gjorde förfrågan $ip_number -- IP-nummret för datorn som gjorde förfrågan $bin-ip_number -- IP-nummret för datorn som gjorde förfrågan som
10c7e11999-12-28Martin Nilsson  binärdata i nätverksoktettordning
b796b51998-11-18Per Hedbor  $cern_date -- Ett datum som det ska vara enligt Cern Common Log
10c7e11999-12-28Martin Nilsson  file specifikationen
b796b51998-11-18Per Hedbor $bin-date -- Tiden för requesten som sekunder sedan 1970, binärt i nätverksoktettordning. $method -- Förfrågningsmetoden (GET, POST etc) $resource -- Resursidentifieraren (filnamnet) $protocol -- Protokollet som användes för att fråga efter filen $response -- Den skickade svarskoden $bin-response -- Den skickade svarskoden som ett binärt ord (2 oktetter) i nätverksoktettordning $length -- Längden av datan som skickades som svar till klienten $bin-length -- Samma sak, men som ett 4 oktetters ord i
10c7e11999-12-28Martin Nilsson  nätverksoktettordning.
b796b51998-11-18Per Hedbor $request-time -- Tiden som requeten tog i sekunder $referer -- Headern 'referer' från förfrågan eller '-'. $user_agent -- Headern 'User-Agent' från förfrågan eller '-'. $user -- Den autentifierade användarens namn, eller '-'
10c7e11999-12-28Martin Nilsson $user_id -- Ett unikt användarid. Tas från kakan RoxenUserID, du
b796b51998-11-18Per Hedbor  måste slå på kaksättningsfunktionaliteten i de globala inställningarna. '0' används för de förfrågningar som inte har kakan. </pre>");
a8f1b32000-01-31Per Hedbor 
10c7e11999-12-28Martin Nilsson 
14179b1997-01-29Per Hedbor  defvar("Log", 1, "Logging: Enabled", TYPE_FLAG, "Log requests");
b796b51998-11-18Per Hedbor  deflocaledoc("svenska", "Log", "Loggning: På", "Ska roxen logga alla förfrågningar till en logfil?");
dfe0362000-03-19Martin Nilsson  defvar("LogFile", "$LOGDIR/"+Roxen.short_name(name)+"/Log",
14179b1997-01-29Per Hedbor  "Logging: Log file", TYPE_FILE, "The log file. "
f7d9811997-09-12Per Hedbor  "" "A file name. May be relative to "+getcwd()+"." " Some substitutions will be done:" "<pre>"
b796b51998-11-18Per Hedbor  "%y Year (e.g. '1997')\n" "%m Month (e.g. '08')\n" "%d Date (e.g. '10' for the tenth)\n"
3bb38c2000-01-20Martin Bähr  "%h Hour (e.g. '00')\n" "%H Hostname\n" "</pre>"
c5e0961999-10-04Per Hedbor  ,0, lambda(){ return !query("Log");});
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "LogFile", "Logging: Logdatei", "Ein Dateiname. Kann relativ zu "+getcwd()+" sein." "Einige Ersetzungen werden vorgenommen:" #"<pre> %y Jahr (z.B. '1997') %m Monat (z.B. '08') %d Tag (z.B. '10' für den 10. des Monats) %h Stunden (z.B. '00') </pre>");
10c7e11999-12-28Martin Nilsson  deflocaledoc("svenska", "LogFile",
3b17831998-11-22Per Hedbor  "Loggning: Loggfil",
b796b51998-11-18Per Hedbor  "Filen som roxen loggar i. Filnamnet kan vara relativt " +getcwd()+ #". Du kan använda några kontrollkoder för att få flera loggfiler och automatisk loggrotation: <pre> %y År (t.ex. '1997') %m Månad (t.ex. '08') %d Datum (t.ex. '10') %h Timme (t.ex. '00') </pre>");
10c7e11999-12-28Martin Nilsson  defvar("NoLog", ({ }),
9b9f701997-08-12Per Hedbor  "Logging: No Logging for", TYPE_STRING_LIST|VAR_MORE,
14179b1997-01-29Per Hedbor  "Don't log requests from hosts with an IP number which matches any " "of the patterns in this list. This also affects the access counter "
c5e0961999-10-04Per Hedbor  "log.\n",0, lambda(){ return !query("Log");});
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "NoLog", "Logging: Kein Log für", #"Für die folgenden IP-Adressen werden keine Log-Einträge vorgenommen. Dies hat auch Einfluss auf den Access-Counter.");
10c7e11999-12-28Martin Nilsson  deflocaledoc("svenska", "NoLog",
3b17831998-11-22Per Hedbor  "Loggning: Logga inte för",
b796b51998-11-18Per Hedbor #"Logga inte några förfrågningar vars IP-nummer matchar något av de mönster som står i den här listan. Den här variabeln påverkar även &lt;accessed&gt; RXML-styrkoden.");
10c7e11999-12-28Martin Nilsson 
b653f51999-05-18Martin Stjernholm  defvar("Domain", roxen->get_domain(), "Domain", TYPE_STRING,
b796b51998-11-18Per Hedbor  "The domainname of the server. The domainname is used " " to generate default URLs, and to gererate email addresses");
e6f83d2000-03-06Peter Bortas  deflocaledoc( "deutsch", "Domain", "DNS-Domain", #"Der Domainname des Servers, der für die Generierung der Standard-URLs und Email-Adressen verwendet wird");
10c7e11999-12-28Martin Nilsson  deflocaledoc( "svenska", "Domain",
b796b51998-11-18Per Hedbor  "DNS Domän", #"Serverns domännamn. Det av en del RXML styrkoder för att generara epostadresser, samt för att generera skönskvärdet för serverurl variablen.");
a8f1b32000-01-31Per Hedbor 
14179b1997-01-29Per Hedbor 
18f5fa2000-03-26Martin Nilsson  defvar("MyWorldLocation", "http://"+gethostname()+"/", "Server URL", TYPE_STRING,
c5e0961999-10-04Per Hedbor  "This is the main server URL, where your start page is located.");
e6f83d2000-03-06Peter Bortas  deflocaledoc( "deutsch", "MyWorldLocation", "Server-URL", "Dies ist die URL des Haupt-Servers, auf dem die Startseite " "abgelegt ist.");
b796b51998-11-18Per Hedbor  deflocaledoc( "svenska", "MyWorldLocation", "Serverns URL",
10c7e11999-12-28Martin Nilsson #"Det här är huvudURLen till din startsida. Den används av många
b796b51998-11-18Per Hedbor  moduler för att bygga upp absoluta URLer från en relativ URL.");
c5e0961999-10-04Per Hedbor 
f406ba1999-11-27Per Hedbor  defvar("URLs", ({"http://*:80/"}), "URLs", TYPE_STRING_LIST|VAR_INITIAL,
0387982000-02-28Per Hedbor  "Bind to these URLs. You can use '*' and '?' to perform globbing " "(using any of these will default to binding to all IP-numbers on " "your machine). The possible protocols are http, fhttp (a faster " "version of the normal HTTP protocol, but not 100% compatible with " "all modules) https, ftp, ftps, gopher and tetris.");
c5e0961999-10-04Per Hedbor 
199d031999-09-05Francesco Chemolli  defvar("InternalLoc", "/_internal/",
10c7e11999-12-28Martin Nilsson  "Internal module resource mountpoint",
f406ba1999-11-27Per Hedbor  TYPE_LOCATION|VAR_MORE|VAR_DEVELOPER,
5839c31999-01-22Marcus Comstedt  "Some modules may want to create links to internal resources. " "This setting configures an internally handled location that can " "be used for such purposes. Simply select a location that you are " "not likely to use for regular resources.");
f406ba1999-11-27Per Hedbor 
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "InternalLoc", "Interner Modulressourcen-Mountpoint", #"Einige Module erzeugen Links auf interne Ressourcen. Diese Einstellung bestimmt eine intern verwandte Position im virtuellen Dateisystem, um solche Zwecke zu erfüllen. Es sollte ein Wert benutzt werden, der nicht durch andere Ressourcen benutzt wird.");
10c7e11999-12-28Martin Nilsson  deflocaledoc("svenska", "InternalLoc",
5839c31999-01-22Marcus Comstedt  "Intern modulresursmountpoint", #"Somliga moduler kan vilja skapa länkar till interna resurser. Denna inställning konfigurerar en internt hanterad location som kan användas för sådana ändamål. Välj bara en location som du förmodligen inte kommer behöva för vanliga resurser.");
199d031999-09-05Francesco Chemolli  // throttling-related variables defvar("throttle",0,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Server: Enabled",TYPE_FLAG,
10c7e11999-12-28Martin Nilsson #"If set, per-server bandwidth throttling will be enabled. It will allow you to limit the total available bandwidth for
199d031999-09-05Francesco Chemolli this Virtual Server.<BR>Bandwidth is assigned using a Token Bucket. The principle under which it works is: for each byte we send we use a token. Tokens are added to a repository at a constant rate. When there's not enough, we can't transmit. When there's too many, they \"spill\" and are lost."); //TODO: move this explanation somewhere on the website and just put a link.
e6f83d2000-03-06Peter Bortas  deflocaledoc( "deutsch", "throttle", "Bandbreitenbegrenzung: Server: Aktiviert", #"Wenn gesetzt, wird pro Server eine Bandbreitenbegrenzung aktiviert. Dadurch kann man die zur Verfügung stehende Bandbreite für diesen virtuellen Server begrenzen.<br>");
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle", "Bandviddsbegränsning: Servernivå: På",
10c7e11999-12-28Martin Nilsson  #"Om den här variablen är på så kommer bandvisddsbegränsning
4d16831999-11-17Per Hedbor på servernivå att ske. Det gör det möjligt för dig att begränsa den totala bandvidden som den här virtuella servern använder. <p>
10c7e11999-12-28Martin Nilsson Bandvidden räknas ut genom att använda en poletthink. Principen som den
4d16831999-11-17Per Hedbor arbetar efter är: För varje byte som sänds så används en polett, poletter stoppas i hinken i en konstant hastighet. När det inte finns några poletter så avstännar dataskickande tills en polett blir tillgänglig. När det är för många poletter i hinken så kommer de nya som kommer in att \"ramla ut\".");
199d031999-09-05Francesco Chemolli  defvar("throttle_fill_rate",102400,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Server: Average available bandwidth",
199d031999-09-05Francesco Chemolli  TYPE_INT,
10c7e11999-12-28Martin Nilsson #"This is the average bandwidth available to this Virtual Server in
199d031999-09-05Francesco Chemolli bytes/sec (the bucket \"fill rate\").", 0,arent_we_throttling_server);
e6f83d2000-03-06Peter Bortas  deflocaledoc( "deutsch", "throttle_fill_rate", "Bandbreitenbegrenzung: Server: " "Durchschnittliche Bandbreite", "Dies ist die durchschnittliche Bandbreite, die " "für diesen virtuellen Server zur Verfügung steht. " "(in Bytes/Sekunde).");
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle_fill_rate", "Bandviddsbegränsning: Servernivå:" " Genomsnittlig tillgänglig bandvidd", "Det här är den genomsnittliga bandvidden som är tillgänglig " "för servern (hastigheten med vilken hinken fylls)");
199d031999-09-05Francesco Chemolli  defvar("throttle_bucket_depth",1024000,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Server: Bucket Depth", TYPE_INT,
199d031999-09-05Francesco Chemolli #"This is the maximum depth of the bucket. After a long enough period of inactivity, a request will get this many unthrottled bytes of data, before throttling kicks back in.<br>Set equal to the Fill Rate in order not to allow any data bursts. This value determines the length of the time over which the bandwidth is averaged",0,arent_we_throttling_server);
4d16831999-11-17Per Hedbor 
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle_bucket_depth", "Bandviddsbegränsning: Servernivå:" " Hinkstorlek", "Det här är det maximala antalet poletter som får plats " "i hinken. Om det här värdet är lika stort som den " "genomsnittliga tillgängliga bandvidden så tillåts inga " "tillfälliga datapulser när servern har varit inaktiv ett tag" " utan data skickas alltid med max den bandvidden");
10c7e11999-12-28Martin Nilsson 
199d031999-09-05Francesco Chemolli  defvar("throttle_min_grant",1300,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Server: Minimum Grant", TYPE_INT,
199d031999-09-05Francesco Chemolli #"When the bandwidth availability is below this value, connections will be delayed rather than granted minimal amounts of bandwidth. The purpose is to avoid sending too small packets (which would increase the IP overhead)", 0,arent_we_throttling_server);
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle_min_grant", "Bandviddsbegränsning: Servernivå:" " Minimalt antal bytes",
10c7e11999-12-28Martin Nilsson #"När det tillgängliga antalet poletter (alltså bytes) är mindre än det här
4d16831999-11-17Per Hedbor värdet så fördröjs förbindelser, alternativet är att skicka små paket, vilket öker overheaden som kommer till från IP och TCP paketheadrar." );
199d031999-09-05Francesco Chemolli  defvar("throttle_max_grant",14900,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Server: Maximum Grant", TYPE_INT,
199d031999-09-05Francesco Chemolli #"This is the maximum number of bytes assigned in a single request to a connection. Keeping this number low will share bandwidth more evenly among the pending connections, but keeping it too low will increase IP overhead and (marginally) CPU usage. You'll want to set it just a tiny bit lower than any integer multiple of your network's MTU (typically 1500 for ethernet)",0,arent_we_throttling_server);
10c7e11999-12-28Martin Nilsson 
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle_max_grant", "Bandviddsbegränsning: Servernivå:" " Maximalt antal bytes", #"Det här är det maximala antalet bytes som en förbindelse kan få. Om det här värdet är lågt så fördelas bandvidden mer jämnt mellan olika förbindelser, men om det är för lågt så ökar overeden från IP och TCP. <p> Sätt det till ett värde som är aningens lägre än en jämn multipel av ditt nätverks MTU (normala ethernetförbindelser har en MTU på 1500) " );
199d031999-09-05Francesco Chemolli  defvar("req_throttle", 0,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Request: Enabled", TYPE_FLAG,
199d031999-09-05Francesco Chemolli #"If set, per-request bandwidth throttling will be enabled." );
4d16831999-11-17Per Hedbor 
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "req_throttle", "Bandviddsbegränsning: Förbindelsenivå: På", "Om på så begränsas bandvidden individuellt på förbindelser" );
10c7e11999-12-28Martin Nilsson 
199d031999-09-05Francesco Chemolli  defvar("req_throttle_min", 1024,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Request: Minimum guarranteed bandwidth",
199d031999-09-05Francesco Chemolli  TYPE_INT, #"The maximum bandwidth each connection (in bytes/sec) can use is determined
10c7e11999-12-28Martin Nilsson combining a number of modules. But doing so can lead to too small
199d031999-09-05Francesco Chemolli or even negative bandwidths for particularly unlucky requests. This variable guarantees a minimum bandwidth for each request", 0,arent_we_throttling_request);
10c7e11999-12-28Martin Nilsson 
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "req_throttle_min", "Bandviddsbegränsning: Förbindelsenivå: Minimal bandvidd",
10c7e11999-12-28Martin Nilsson #"Den maximala bandvidden som varje förbindelse får bestäms av en kombination
4d16831999-11-17Per Hedbor av de bandviddsbegränsningsmoduler som är adderade i servern. Men ibland
10c7e11999-12-28Martin Nilsson så blir det framräknade värdet väldigt lågt, och en del riktigt otursamma
4d16831999-11-17Per Hedbor förbindelser kan råka hamna på 0 eller mindre bytes per sekund. <p>Den här variablen garanterar en vis minimal bandvidd för alla requests" );
199d031999-09-05Francesco Chemolli  defvar("req_throttle_depth_mult", 60.0,
4d16831999-11-17Per Hedbor  "Bandwidth Throttling: Request: Bucket Depth Multiplier",
199d031999-09-05Francesco Chemolli  TYPE_FLOAT,
10c7e11999-12-28Martin Nilsson #"The average bandwidth available for each request will be determined by
199d031999-09-05Francesco Chemolli the modules combination. The bucket depth will be determined multiplying the rate by this factor.", 0,arent_we_throttling_request);
e6f83d2000-03-06Peter Bortas  //FIXME: German Translation missing.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "req_throttle_depth_mult", "Bandviddsbegränsning: Förbindelsenivå: Hinkstorlek",
10c7e11999-12-28Martin Nilsson #"Den genomsnittliga bandvidden som varje förbindelse bestäms av
4d16831999-11-17Per Hedbor de adderade bandvidsbegränsningsmodulerna. Hinkstorleken bestäms genom att multiplicera detta värde med den här faktorn.");
94d4752000-04-05Martin Nilsson  defvar("ZNoSuchFile", #" <html><head> <title>404 - Page not found</title> </head> <body alink=\"#000000\" bgcolor=\"#ffffff\" bottommargin=\"0\" leftmargin=\"0\" link=\"#ce5c00\" marginheight=\"2\" marginwidth=\"0\" rightmargin=\"0\" text=\"#333333\" topmargin=\"2\" vlink=\"#ce5c00\"> <table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"> <tr> <td><img src=\"/internal-roxen-page-not-found\" border=\"0\" alt=\"Page not found\" hspace=\"2\" /></td> <td>&nbsp;</td> <td align=\"right\"><b>&roxen.version;</b></td> </tr> <tr> <td width=\"100%\" height=\"21\" colspan=\"3\" background=\"/internal-roxen-tile\"><img src=\"/internal-roxen-unit\" alt=\"\" /></td> </tr> </table> <font face=\"lucida,helvetica,arial\"> <h2>&nbsp;Unable to retrieve &page.virtfile;.</h2> <br /><br /> <blockquote> If you feel that this is a configuration error, please contact the administrators or the author of the <if referrer> <a href=\"&client.referrer;\">referring</a> </if><else> referring </else> page. </blockquote> </font> </body> ",
a7e39f2000-02-04Per Hedbor  "Messages: No such file",TYPE_TEXT_FIELD, "What to return when there is no resource or file available " "at a certain location.");
e6f83d2000-03-06Peter Bortas  deflocaledoc("deutsch", "ZNoSuchFile", "Mitteilungen: Datei nicht gefunden", #"Dieser Text wird angezeigt, wenn eine nicht verfügbare Datei aufgerufen wird. '$File' wird ersetzt durch den Dateinamen, '$Me' durch die Server-URL");
a7e39f2000-02-04Per Hedbor  deflocaledoc("svenska", "ZNoSuchFile", "Meddelanden: Filen finns inte", #"Det här meddelandet returneras om en användare frågar efter en resurs som inte finns. '$File' byts ut mot den efterfrågade resursen, och '$Me' med serverns URL");
c45e3f2000-02-16Per Hedbor  definvisvar( "no_delayed_load", 0, TYPE_FLAG );
a7e39f2000-02-04Per Hedbor 
c5e0961999-10-04Per Hedbor  setvars(retrieve("spider#0", this_object()));
199d031999-09-05Francesco Chemolli 
07c9921999-11-23Per Hedbor  if (query("throttle"))
c5e0961999-10-04Per Hedbor  {
199d031999-09-05Francesco Chemolli  throttler=.throttler(); throttler->throttle(query("throttle_fill_rate"), query("throttle_bucket_depth"), query("throttle_min_grant"), query("throttle_max_grant")); } } int arent_we_throttling_server () { return !query("throttle"); } int arent_we_throttling_request() { return !query("req_throttle");
14179b1997-01-29Per Hedbor }
b6fb051999-11-02Per Hedbor  string _sprintf( ) { return "Configuration("+name+")"; }