199d031999-09-05Francesco Chemolli /* * A vitual server's main configuration * (C) 1996, 1999 Idonex AB. */
4d16831999-11-17Per Hedbor constant cvs_version = "$Id: configuration.pike,v 1.222 1999/11/17 15:14:20 per Exp $"; 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 
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 #define THROTTLING_DEBUG(X) perror("Throttling: "+X+"\n") #else #define THROTTLING_DEBUG(X) #endif
b1fca01996-11-12Per Hedbor /* A configuration.. */
3b17831998-11-22Per Hedbor #include "rxml.pike";
14179b1997-01-29Per Hedbor 
199d031999-09-05Francesco Chemolli object throttler=0;
14179b1997-01-29Per Hedbor function store = roxen->store; function retrieve = roxen->retrieve; function remove = roxen->remove; function do_dest = roxen->do_dest;
b1fca01996-11-12Per Hedbor object types_module; object auth_module; object dir_module; function types_fun; function auth_fun; string name; mapping variables = ([]);
c7a5f01999-02-16Per Hedbor  string get_doc_for( string region, string variable ) { object module; 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 ]; }
14179b1997-01-29Per Hedbor public mixed query(string var) { if(var && variables[var]) return variables[var][ VAR_VALUE ]; if(!var) return variables;
383fa91997-01-29Per Hedbor  error("query("+var+"): Unknown variable.\n");
14179b1997-01-29Per Hedbor } mixed set(string var, mixed val) { if(variables[var]) return variables[var][VAR_VALUE] = val; error("set("+var+"). Unknown variable.\n"); } int setvars( mapping (string:mixed) vars ) { string v; foreach( indices( vars ), v ) if(variables[v]) variables[v][ VAR_VALUE ] = vars[ v ]; return 1; } void killvar(string name) { m_delete(variables, name); }
4d16831999-11-17Per Hedbor constant ConfigurableWrapper = roxen.ConfigurableWrapper;
7acb8e1998-07-07Henrik Grubbström (Grubba) 
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 {
c5e0961999-10-04Per Hedbor  variables[var] = allocate( VAR_SIZE );
14179b1997-01-29Per Hedbor  variables[var][ VAR_VALUE ] = value;
13ff621997-08-12Per Hedbor  variables[var][ VAR_TYPE ] = type & VAR_TYPE_MASK;
14179b1997-01-29Per Hedbor  variables[var][ VAR_DOC_STR ] = doc_str; variables[var][ VAR_NAME ] = name; variables[var][ VAR_MISC ] = misc;
9b9f701997-08-12Per Hedbor 
df6cd11998-10-13Per Hedbor  Locale.Roxen.standard ->register_module_doc( this_object(), var, name, doc_str );
7acb8e1998-07-07Henrik Grubbström (Grubba)  type &= (VAR_EXPERT | VAR_MORE);
c5e0961999-10-04Per Hedbor  if (functionp(not_in_config)) if (type)
7acb8e1998-07-07Henrik Grubbström (Grubba)  variables[var][ VAR_CONFIGURABLE ] = ConfigurableWrapper(type, not_in_config)->check;
c5e0961999-10-04Per Hedbor  else
7acb8e1998-07-07Henrik Grubbström (Grubba)  variables[var][ VAR_CONFIGURABLE ] = not_in_config;
c5e0961999-10-04Per Hedbor  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;
14179b1997-01-29Per Hedbor  variables[var][ VAR_SHORTNAME ] = var; }
df6cd11998-10-13Per Hedbor void deflocaledoc( string locale, string variable,
b796b51998-11-18Per Hedbor  string name, string doc, mapping|void translate )
df6cd11998-10-13Per Hedbor { if( !Locale.Roxen[locale] ) report_debug("Invalid locale: "+locale+". Ignoring.\n"); else Locale.Roxen[locale]
b796b51998-11-18Per Hedbor  ->register_module_doc( this_object(), variable, name, doc, translate );
df6cd11998-10-13Per Hedbor }
14179b1997-01-29Per Hedbor int definvisvar(string var, mixed value, int type) { return defvar(var, value, "", type, "", 0, 1); }
5839c31999-01-22Marcus Comstedt string query_internal_location(object|void mod) {
c5e0961999-10-04Per Hedbor  return QUERY(InternalLoc)+(mod?replace(otomod[mod]||"", "#", "!")+"/":"");
5839c31999-01-22Marcus Comstedt }
b1fca01996-11-12Per Hedbor  string query_name() {
c5e0961999-10-04Per Hedbor  if(strlen(QUERY(name))) return QUERY(name);
b1fca01996-11-12Per Hedbor  return name; } string comment() { return QUERY(comment); }
38dca81996-12-10Per Hedbor class Priority
27b0e11996-11-26Per Hedbor {
b1fca01996-11-12Per Hedbor  array (object) url_modules = ({ }); array (object) logger_modules = ({ }); array (object) location_modules = ({ }); array (object) filter_modules = ({ }); array (object) last_modules = ({ }); array (object) first_modules = ({ }); mapping (string:array(object)) file_extension_modules = ([ ]);
ae32d01998-03-23David Hedbor  mapping (object:multiset) provider_modules = ([ ]);
38dca81996-12-10Per Hedbor  void stop() {
c7a5f01999-02-16Per Hedbor  foreach(url_modules, object m) CATCH("stopping url modules",m->stop && m->stop()); foreach(logger_modules, object m) CATCH("stopping logging modules",m->stop && m->stop()); foreach(filter_modules, object m) CATCH("stopping filter modules",m->stop && m->stop()); foreach(location_modules, object m) CATCH("stopping location modules",m->stop && m->stop()); foreach(last_modules, object m) CATCH("stopping last modules",m->stop && m->stop()); foreach(first_modules, object m) CATCH("stopping first modules",m->stop && m->stop()); foreach(indices(provider_modules), object m) 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. */ array (object) allocate_pris() {
c5e0961999-10-04Per Hedbor  return allocate(10, Priority)();
b1fca01996-11-12Per Hedbor }
c5e0961999-10-04Per Hedbor class Bignum { #if constant(Gmp.mpz)
e8790b1998-02-19Per Hedbor  object gmp = Gmp.mpz();
27b0e11996-11-26Per Hedbor  float mb()
b1fca01996-11-12Per Hedbor  {
e8790b1998-02-19Per Hedbor  return (float)(gmp/1024)/1024.0; } object `+(int i) { gmp = gmp+i; return this_object(); } object `-(int i) { gmp = gmp-i; return this_object();
b1fca01996-11-12Per Hedbor  }
27b0e11996-11-26Per Hedbor #else
c5e0961999-10-04Per Hedbor  int n; object `+(int i) { n+=i; return this_object(); } object `-(int i) { n-=i; return this_object(); } float mb() {return (float)n/ 1024.0; }
27b0e11996-11-26Per Hedbor #endif
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 
27b0e11996-11-26Per Hedbor object sent=Bignum(); // Sent data object hsent=Bignum(); // Sent headers object received=Bignum(); // 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.
86e7d31998-04-28Wilhelm Köhler function 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
b1fca01996-11-12Per Hedbor private array (object) pri = allocate_pris(); // All enabled modules in this virtual server.
c5e0961999-10-04Per Hedbor // The format is "module":([ "copies":([ num:instance, ... ]) ])
b1fca01996-11-12Per Hedbor public mapping (string:mapping(string:mixed)) modules = ([]); // A mapping from objects to module names public mapping (object:string) otomod = ([]); // 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=([]);
ae32d01998-03-23David Hedbor private mapping (string:array (object)) 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()); for(int i=0; i<10; i++) CATCH("stopping priority group", pri[i] && pri[i]->stop && pri[i]->stop());
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 {
14179b1997-01-29Per Hedbor  mixed tmp; if(!types_fun) return to?({ "application/octet-stream", 0 }):"application/octet-stream";
41b77c1999-07-15David Hedbor  string ext=myext || extension(file);
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". array (object) get_providers(string provides) {
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]) { int i; provider_module_cache[provides] = ({ }); for(i = 9; i >= 0; i--) {
9336a81998-07-09Henrik Grubbström (Grubba)  foreach(indices(pri[i]->provider_modules), object d)
ae32d01998-03-23David Hedbor  if(pri[i]->provider_modules[ d ][ provides ]) 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". object get_provider(string provides) { array (object) prov = get_providers(provides); 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 { array (object) prov = get_providers(provides); array error;
bdb8da1998-09-02Johan Schön  array a=({ }); mixed m;
9bb8131998-09-12Per Hedbor  foreach(prov, object mod) {
ae32d01998-03-23David Hedbor  if(!objectp(mod)) continue; 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]; roxen_perror(describe_backtrace(error)); }
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) {
b5887c1998-05-28Henrik Grubbström (Grubba)  foreach(get_providers(provides), object mod) {
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 
b1fca01996-11-12Per Hedbor array (function) file_extension_modules(string ext, object id) { if(!file_extension_module_cache[ext]) { int i; file_extension_module_cache[ext] = ({ }); for(i=9; i>=0; i--) { object *d, p; 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]; } array (function) url_modules(object id) { if(!url_module_cache) { int i; url_module_cache=({ }); for(i=9; i>=0; i--) { object *d, p; 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 = ([]);
74f9711999-09-26Martin Stjernholm mapping api_functions(void|object id)
4f4bc11998-02-04Per Hedbor { return copy_value(api_module_cache); }
b1fca01996-11-12Per Hedbor array (function) logger_modules(object id) { if(!logger_module_cache) { int i; logger_module_cache=({ }); for(i=9; i>=0; i--) { object *d, p; if(d=pri[i]->logger_modules) foreach(d, p) if(p->log) logger_module_cache += ({ p->log }); } } return logger_module_cache; } array (function) last_modules(object id) { if(!last_module_cache) { int i; last_module_cache=({ }); for(i=9; i>=0; i--) { object *d, p; 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__ static mixed strip_fork_information(object id) { 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__ */
b1fca01996-11-12Per Hedbor array (function) first_modules(object id) { 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--) { object *d, 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; } array location_modules(object id) { 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--) { object *d, 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; } array filter_modules(object id) { if(!filter_module_cache) { int i; filter_module_cache=({ }); for(i=9; i>=0; i--) { object *d, p; if(d=pri[i]->filter_modules) foreach(d, p) if(p->filter) filter_module_cache+=({ p->filter }); } } return filter_module_cache; }
14179b1997-01-29Per Hedbor void init_log_file()
b1fca01996-11-12Per Hedbor {
14179b1997-01-29Per Hedbor  remove_call_out(init_log_file); if(log_function) destruct(function_object(log_function)); // Free the old one.
b1fca01996-11-12Per Hedbor 
14179b1997-01-29Per Hedbor  if(query("Log")) // Only try to open the log file if logging is enabled!!
b1fca01996-11-12Per Hedbor  {
f7d9811997-09-12Per Hedbor  mapping m = localtime(time());
119e241997-05-24Henrik Grubbström (Grubba)  string logfile = query("LogFile");
0a21221998-01-08Henrik Grubbström (Grubba)  m->year += 1900; /* Adjust for years being counted since 1900 */ m->mon++; /* Adjust for months being counted 0-11 */
f7d9811997-09-12Per Hedbor  if(m->mon < 10) m->mon = "0"+m->mon;
0a21221998-01-08Henrik Grubbström (Grubba)  if(m->mday < 10) m->mday = "0"+m->mday;
f7d9811997-09-12Per Hedbor  if(m->hour < 10) m->hour = "0"+m->hour; logfile = replace(logfile,({"%d","%m","%y","%h" }),
0a21221998-01-08Henrik Grubbström (Grubba)  ({ (string)m->mday, (string)(m->mon), (string)(m->year),(string)m->hour,}));
f7d9811997-09-12Per Hedbor  if(strlen(logfile))
b1fca01996-11-12Per Hedbor  {
f7d9811997-09-12Per Hedbor  do { object lf=open( logfile, "wac"); if(!lf) { mkdirhier(logfile); if(!(lf=open( logfile, "wac"))) {
b461641998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->failed_to_open_logfile(logfile));
f7d9811997-09-12Per Hedbor  log_function=0; break;
119e241997-05-24Henrik Grubbström (Grubba)  }
f7d9811997-09-12Per Hedbor  } log_function=lf->write; // Function pointer, speeds everything up (a little..). lf=0; } while(0); } else log_function=0;
14179b1997-01-29Per Hedbor  call_out(init_log_file, 60); } else log_function=0;
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)  // FIXME: This looks like a bug. // Is it supposed to strip all initial whitespace, or do what it does? // /grubba 1997-10-03 while(s[0] == ' ') s = s[1..]; while(s[0] == '\t') s = s[1..];
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 "-"; return tmp[0]; // username only, no password } public void log(mapping file, object request_id) {
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  if(QUERY(NoLog) && _match(request_id->remoteaddr, QUERY(NoLog))) return; if(!(form=log_format[(string)file->error])) form = log_format["*"]; if(!form) return; form=replace(form, ({ "$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"
14179b1997-01-29Per Hedbor  }), ({ (string)request_id->remoteaddr,
71c7b11998-03-02Henrik Grubbström (Grubba)  host_ip_to_int(request_id->remoteaddr), cern_http_date(time(1)), unsigned_to_bin(time(1)), (string)request_id->method,
dfb4ec1999-05-20Francesco Chemolli  http_encode_string((string)request_id->not_query), 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]:"-"), http_encode_string(sizeof(request_id->client||({}))?request_id->client*" ":"-"), extract_user(request_id->realauth), (string)request_id->cookies->RoxenUserID,
d9624c1998-04-03Henrik Grubbström (Grubba)  (string)(time(1)-request_id->time)
71c7b11998-03-02Henrik Grubbström (Grubba)  }));
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  if(!sent||!received||!hsent)
c5e0961999-10-04Per Hedbor  return LOCALE->status_bignum_gone();
14179b1997-01-29Per Hedbor 
b461641998-10-11Henrik Grubbström (Grubba)  res = "<table>"; res += LOCALE->config_status(sent->mb(), (sent->mb()/dt) * 8192.0, hsent->mb(), requests, (((float)requests * 60.0)/dt), received->mb());
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"; }
14179b1997-01-29Per Hedbor 
12a9c51997-08-11Henrik Grubbström (Grubba)  return res;
14179b1997-01-29Per Hedbor }
a78a591997-04-28Henrik Grubbström (Grubba) public string *userinfo(string u, object|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 }
a78a591997-04-28Henrik Grubbström (Grubba) public string *userlist(object|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 }
a78a591997-04-28Henrik Grubbström (Grubba) public string *user_from_uid(int u, object|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 }
6103bc1999-10-09Henrik Grubbström (Grubba) public string last_modified_by(object file, object id) { int *s; int uid; mixed *u; 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)
06026c1999-10-19Henrik Grubbström (Grubba)  object f = open("roxen-images/dir/"+from+".gif","r"); if (f) { return (["file":f, "type":"image/gif"]); } else { // File not found. return 0; }
14179b1997-01-29Per Hedbor } private static int nest = 0; #ifdef MODULE_LEVEL_SECURITY private mapping misc_cache=([]); int|mapping check_security(function a, object id, void|int slevel) { 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; 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;
14179b1997-01-29Per 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)) return 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;
14179b1997-01-29Per 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. if(id->misc->proxyauth && id->misc->proxyauth[0] && level[1](id->misc->proxyauth[1])) return 0; return http_proxy_auth_required(seclevels[2]); } 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.
c5e0961999-10-04Per Hedbor  return http_auth_failed(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.
c5e0961999-10-04Per Hedbor  return http_auth_failed(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();
c5e0961999-10-04Per Hedbor  foreach(indices(otomod), object 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) { object bar=Image.image(30,256); 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); return bar->togif(255,255,255); }
14179b1997-01-29Per Hedbor // Inspired by the internal-gopher-... thingie, this is the images // from the configuration interface. :-) private mapping internal_roxen_image(string from) {
c5e0961999-10-04Per Hedbor  // changed 970820 by js to allow for jpeg images
14179b1997-01-29Per Hedbor  sscanf(from, "%s.gif", from); sscanf(from, "%s.jpg", from);
fc94331997-10-25Per Hedbor 
14179b1997-01-29Per Hedbor  // Disallow "internal-roxen-..", 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) // /internal-roxen-../.. was never possible, since that would be remapped to // /..
fc94331997-10-25Per Hedbor  from -= ".";
4154e61997-08-20Johan Schön 
fc94331997-10-25Per Hedbor  // New idea: Automatically generated colorbar. Used by wizard code... int hue,bright,w; if(sscanf(from, "%*s:%d,%d,%d", hue, bright,w)==4) return http_string_answer(draw_saturation_bar(hue,bright,w),"image/gif");
c5e0961999-10-04Per Hedbor  if(Stdio.File f=open("roxen-images/"+from+".gif", "r"))
06026c1999-10-19Henrik Grubbström (Grubba)  return (["file":f, "type":"image/gif"]); else if (f = open("roxen-images/"+from+".jpg", "r")) { return (["file":f, "type":"image/jpeg"]); } else { // 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 = ([]);
14179b1997-01-29Per Hedbor object _lock(object|function f) { 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{
1fab6f1997-09-03Henrik Grubbström (Grubba)  //perror("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  }
1fab6f1997-09-03Henrik Grubbström (Grubba)  //perror("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 if (m->extra_heads && (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; 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.
f6d62d1997-03-26Per Hedbor mapping|int low_get_file(object 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;
14179b1997-01-29Per Hedbor  // 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
41b77c1999-07-15David Hedbor 
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();
41d0f91998-02-20Per Hedbor  if(mappingp(tmp)) { 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  if(!search(file, QUERY(InternalLoc))) { TRACE_ENTER(LOCALE->magic_internal_module_location(), 0); object module; 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 // 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(); if(mappingp(tmp)) { TRACE_LEAVE(""); TRACE_LEAVE(LOCALE->returning_data()); return tmp; } if(objectp( tmp )) { array err; 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(); TRACE_LEAVE(LOCALE->find_file_returned(fid)); if(fid)
14179b1997-01-29Per Hedbor  {
5839c31999-01-22Marcus Comstedt  id->virtfile = loc; 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
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) {
5839c31999-01-22Marcus Comstedt  // This one is here to allow accesses to /local, even if // 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());
5839c31999-01-22Marcus Comstedt 
41b77c1999-07-15David Hedbor  // Keep query (if any). /* FIXME: Should probably keep prestate etc. * /grubba 1999-01-14 */ string new_query = http_encode_string(id->not_query) + "/" + (id->query?("?"+id->query):""); return http_redirect(new_query, id);
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  } }
41b77c1999-07-15David Hedbor 
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  } if(mappingp(fid)) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
41d0f91998-02-20Per Hedbor  return (mapping)fid; }
14179b1997-01-29Per Hedbor  } // Map the file extensions, but only if there is a file...
41b77c1999-07-15David Hedbor  if(objectp(fid) && (tmp = file_extension_modules(loc = 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;
41b77c1999-07-15David Hedbor  loc = extension(id->not_query, id); }
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] ]);
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  mixed handle_request( object id ) { function funp; mixed file;
cfda381999-03-28Henrik Grubbström (Grubba) #ifdef REQUEST_DEBUG werror("CONFIG: handle_request()\n"); #endif /* REQUEST_DEBUG */
c7a5f01999-02-16Per Hedbor  foreach(first_modules(id), funp) { if(file = funp( id )) break;
cfda381999-03-28Henrik Grubbström (Grubba)  if(id->conf != this_object()) { #ifdef REQUEST_DEBUG werror("CONFIG: handle_request(): Redirected (2)\n"); #endif /* REQUEST_DEBUG */
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) { #ifdef REQUEST_DEBUG werror("CONFIG: handle_request(): Recurse\n"); #endif /* REQUEST_DEBUG */
c7a5f01999-02-16Per Hedbor  return handle_request(id);
cfda381999-03-28Henrik Grubbström (Grubba)  }
c7a5f01999-02-16Per Hedbor  file = ret; }
cfda381999-03-28Henrik Grubbström (Grubba) #ifdef REQUEST_DEBUG werror("CONFIG: handle_request(): Done\n"); #endif /* REQUEST_DEBUG */
c7a5f01999-02-16Per Hedbor  return file; }
14179b1997-01-29Per Hedbor mixed get_file(object id, int|void no_magic) { 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(""); }
14179b1997-01-29Per Hedbor  return res; } public array find_dir(string file, object id) { string loc;
29a8071998-08-21David Hedbor  array dir = ({ }), tmp; array | mapping d;
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->list_directory(file), 0);
c7a5f01999-02-16Per Hedbor // file=replace(file, "//", "/");
14179b1997-01-29Per Hedbor 
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 ++;
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)) { if(d->files) { 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;
41d0f91998-02-20Per Hedbor  }
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_no_dir());
14179b1997-01-29Per Hedbor } // Stat a virtual file. public array stat_file(string file, object id) { 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);
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
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("");
d0a47d1997-04-29Henrik Grubbström (Grubba)  return ({ 0775, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  if(!search(file, loc)) {
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; 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) { throw( ({ "File not open for write", backtrace() }) ); } 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. :-) public array open_file(string fname, string mode, object id) { object oc = id->conf; string oq = id->not_query; function funp; mapping file;
cd7ea41998-12-14Peter Bortas  id->not_query = fname;
c7a5f01999-02-16Per Hedbor 
e8790b1998-02-19Per Hedbor  foreach(oc->first_modules(), funp) if(file = funp( id )) break; else if(id->conf != oc) { 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)
001ae71998-10-11Henrik Grubbström (Grubba)  file = http_low_answer(id->misc->error_code, "Failed" );
2380831998-02-22Per Hedbor  else if(id->method!="GET"&&id->method != "HEAD"&&id->method!="POST")
e8790b1998-02-19Per Hedbor  file = http_low_answer(501, "Not implemented."); else file=http_low_answer(404,replace(parse_rxml(query("ZNoSuchFile"),id), ({"$File", "$Me"}), ({fname,query("MyWorldLocation")}))); id->not_query = oq;
c7a5f01999-02-16Per Hedbor 
e8790b1998-02-19Per Hedbor  return ({ 0, file }); }
d08a251999-06-25Per Hedbor  if( file->data )
e8790b1998-02-19Per Hedbor  { file->file = StringFile(file->data); m_delete(file, "data");
2380831998-02-22Per Hedbor  }
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 }
a476711997-10-20Henrik Grubbström (Grubba) public mapping(string:array(mixed)) find_dir_stat(string file, object 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, "//", "/"); 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 roxen_perror(sprintf("conf->find_dir_stat(\"%s\"): url_module returned mapping:%O\n", file, tmp)); #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 ++; 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 roxen_perror(sprintf("conf->find_dir_stat(\"%s\"): url_module returned object:\n", file)); #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 object c = function_object(tmp[1]); 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);
e5bad21998-02-10Per Hedbor  dir = mkmapping(d, Array.map(d, lambda(string f, string base,
a476711997-10-20Henrik Grubbström (Grubba)  object c, object id) {
c5e0961999-10-04Per Hedbor  return c->stat_file(base + f, id);
a476711997-10-20Henrik Grubbström (Grubba)  }, f, c, 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? public array access(string file, object id) { string loc; array s, tmp; file=replace(file, "//", "/"); // "//" is really "/" here... // Map location-modules. foreach(location_modules(id), tmp) { loc = tmp[0]; if((file+"/")==loc) return file+="/"; if(!search(file, loc)) { #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; } } } // Return the _real_ filename of a virtual file, if any. public string real_file(string file, object id) { string loc; string s; array tmp; file=replace(file, "//", "/"); // "//" is really "/" here... if(!id) error("No id passed to real_file"); // Map location-modules. foreach(location_modules(id), tmp) { loc = tmp[0]; if(!search(file, loc)) { #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.
c5e0961999-10-04Per Hedbor int|string try_get_file(string s, object id, int|void status, int|void nocache)
14179b1997-01-29Per Hedbor { string res, q; object fake_id; mapping m;
a6af4d1998-09-17 Rob Young  if(objectp(id)) { // 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 = ([]);
14179b1997-01-29Per Hedbor  fake_id = id->clone_me();
a6af4d1998-09-17 Rob Young  fake_id->misc->common = id->misc->common; } else
14179b1997-01-29Per Hedbor  error("No ID passed to 'try_get_file'\n");
ead2a11999-04-14Henrik Grubbström (Grubba)  if(!id->pragma["no-cache"] && !nocache && (!id->auth || !id->auth[0]))
14179b1997-01-29Per Hedbor  if(res = cache_lookup("file:"+id->conf->name, s)) return res; if(sscanf(s, "%s?%s", s, q)) { string v, name, value; foreach(q/"&", v)
4bf5f91997-03-13David KÃ¥gedal  if(sscanf(v, "%s=%s", name, value))
c5e0961999-10-04Per Hedbor  fake_id->variables[http_decode_string(name)]= http_decode_string(value);
14179b1997-01-29Per Hedbor  fake_id->query=q; } fake_id->raw_url=s; fake_id->not_query=s; fake_id->misc->internal_get=1; if(!(m = get_file(fake_id))) return 0;
889d031999-10-04Per Hedbor 
3510fb1997-11-09Henrik Grubbström (Grubba)  if (!(< 0, 200, 201, 202, 203 >)[m->error]) return 0;
14179b1997-01-29Per Hedbor 
3510fb1997-11-09Henrik Grubbström (Grubba)  if(status) return 1;
a22f6f1999-05-12Per Hedbor  if(m->data) res = m->data; else res="";
14179b1997-01-29Per Hedbor  m->data = 0; if(m->file) {
3a4d7e1997-09-03Per Hedbor  res += m->file->read();
14179b1997-01-29Per Hedbor  destruct(m->file); m->file = 0; } if(m->raw) { res -= "\r"; if(!sscanf(res, "%*s\n\n%s", res)) sscanf(res, "%*s\n%s", res); }
c5e0961999-10-04Per Hedbor  if (!id->auth || !id->auth[0])
ead2a11999-04-14Henrik Grubbström (Grubba)  cache_set("file:"+id->conf->name, s, res);
14179b1997-01-29Per Hedbor  return res; } // Is 'what' a file in our virtual filesystem?
c5e0961999-10-04Per Hedbor int(0..1) is_file(string what, object 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  } } // Save this configuration. If all is included, save all configuration // global variables as well, otherwise only all module variables.
e7e6031999-11-05Per Hedbor void save_me() { save_one( 0 ); }
14179b1997-01-29Per Hedbor void save(int|void all) { mapping mod; if(all) {
c5e0961999-10-04Per Hedbor  store("spider.lpc#0", variables, 0, this_object());
14179b1997-01-29Per Hedbor  start(2); } foreach(values(modules), mod) {
c5e0961999-10-04Per Hedbor  int i; foreach(indices(mod->copies), i)
14179b1997-01-29Per Hedbor  {
c5e0961999-10-04Per Hedbor  store(mod->sname+"#"+i, mod->copies[i]->query(), 0, this_object()); mod->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. int save_one( object o ) { mapping mod; if(!o) {
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"); store(q, o->query(), 0, this_object()); invalidate_cache(); o->start(2, this_object()); invalidate_cache(); return 1;
14179b1997-01-29Per Hedbor } object enable_module( string modname ) {
c5e0961999-10-04Per Hedbor  int id; object moduleinfo;
14179b1997-01-29Per Hedbor  mapping module;
c5e0961999-10-04Per Hedbor  object me; int pr; mixed err; int module_type;
e7e6031999-11-05Per Hedbor  if( sscanf(modname, "%s#%d", modname, id ) != 2 ) /* here we go again... */
4f43eb1999-11-05Per Hedbor  while( modules[modname] && modules[modname]->copies[id] ) id++;
c5e0961999-10-04Per Hedbor 
7f00081998-03-20Per Hedbor  int start_time = gethrtime();
25171c1999-11-06Per Hedbor 
c5e0961999-10-04Per Hedbor  moduleinfo = roxen->find_module( modname );
ad683e1998-05-09Henrik Grubbström (Grubba) 
c5e0961999-10-04Per Hedbor  if (!moduleinfo)
ad683e1998-05-09Henrik Grubbström (Grubba)  {
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
c5e0961999-10-04Per Hedbor  report_debug(" %-30s ... FAILED\n", modname);
3bbda81997-06-11Henrik Grubbström (Grubba) #endif
c5e0961999-10-04Per Hedbor  return 0; }
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
c5e0961999-10-04Per Hedbor  if( id ) report_debug(" %-30s ... ", moduleinfo->get_name()+" copy "+(id+1)); else report_debug(" %-30s ... ", moduleinfo->get_name() );
3bbda81997-06-11Henrik Grubbström (Grubba) #endif
c5e0961999-10-04Per Hedbor  module = modules[ module ]; if(!module) modules[ modname ] = module = ([ ]); if( !module->copies ) module->copies = ([]); if(err = catch(me = moduleinfo->instance(this_object()))) { report_debug("ERROR\n"); werror( describe_backtrace(err) ); return module->copies[id]; } if(module->copies[id]) { if (err = catch{ module->copies[ id ]->stop(); }) { report_error(LOCALE->error_disabling_module(moduleinfo->get_name(), describe_backtrace(err)));
14179b1997-01-29Per Hedbor  }
c5e0961999-10-04Per Hedbor  catch(destruct(module->copies[id]));
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  { 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 " "called in random order", ({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})); 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."); }
14179b1997-01-29Per Hedbor 
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  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 
3bf3451998-10-01Peter Bortas  me->defvar("_seclvl", 0, "Security: Security level", TYPE_INT, "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\".");
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  me->deflocaledoc("svenska", "_seclevels", "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 */
14179b1997-01-29Per 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.");
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  me->deflocaledoc("svenska", "_seclevels", "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 
df6cd11998-10-13Per Hedbor  me->deflocaledoc("svenska", "_comment", "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,
3b17831998-11-22Per Hedbor  "An optional name. You can set it to something to remaind you what "
ad683e1998-05-09Henrik Grubbström (Grubba)  "the module really does.");
14179b1997-01-29Per Hedbor 
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.");
c5e0961999-10-04Per Hedbor  me->setvars(retrieve(modname + "#" + id, this_object()));
33e6351998-02-28Martin Stjernholm 
c5e0961999-10-04Per Hedbor  module->copies[ id ] = me;
37c1b31999-10-12Per Hedbor  otomod[ me ] = modname+"#"+id;
14179b1997-01-29Per Hedbor 
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 report_debug(" ERROR\n"); #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);
0ca08a1999-10-04Marcus Comstedt  if(module->copies) m_delete(module->copies, id);
ad683e1998-05-09Henrik Grubbström (Grubba)  destruct(me); return 0; }
c5e0961999-10-04Per Hedbor  if (err = catch(pr = me->query("_priority"))) {
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();
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_EXTENSION) { 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();
c5e0961999-10-04Per Hedbor  if (arrayp(arr)) {
ad683e1998-05-09Henrik Grubbström (Grubba)  string foo; foreach( me->query_file_extensions(), foo ) if(pri[pr]->file_extension_modules[foo] ) pri[pr]->file_extension_modules[foo]+=({me}); else pri[pr]->file_extension_modules[foo]=({me}); }
c5e0961999-10-04Per Hedbor  })
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)));
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  if(module_type & MODULE_PROVIDER) if (err = catch {
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)  }
c5e0961999-10-04Per Hedbor  })
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->
c5e0961999-10-04Per Hedbor  error_initializing_module_copy(moduleinfo->get_name(), describe_backtrace(err))); if(module_type & MODULE_TYPES)
ad683e1998-05-09Henrik Grubbström (Grubba)  { types_module = me; types_fun = me->type_from_extension; }
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 
c5e0961999-10-04Per Hedbor  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)  } invalidate_cache();
c5e0961999-10-04Per Hedbor  report_debug(" OK %5.1fms.\n", (gethrtime()-start_time)/1000.0);
ad683e1998-05-09Henrik Grubbström (Grubba)  return me;
14179b1997-01-29Per Hedbor } // Called from the configuration 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  } } int disable_module( string modname ) { object me;
c5e0961999-10-04Per Hedbor  int id, pr;
14179b1997-01-29Per Hedbor  sscanf(modname, "%s#%d", modname, id );
c5e0961999-10-04Per Hedbor  object moduleinfo = roxen->find_module( modname ); mapping module = modules[ modname ];
14179b1997-01-29Per Hedbor  if(!module) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->disable_nonexistant_module(modname));
14179b1997-01-29Per Hedbor  return 0; }
c5e0961999-10-04Per Hedbor  me = module->copies[id]; m_delete(module->copies, id); 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) {
c5e0961999-10-04Per Hedbor  if( id ) report_error(LOCALE->disable_module_failed(moduleinfo->get_name() +" # "+id)); else report_error(LOCALE->disable_module_failed(moduleinfo->get_name()));
14179b1997-01-29Per Hedbor  return 0; } if(me->stop) me->stop(); #ifdef MODULE_DEBUG
c5e0961999-10-04Per Hedbor  if( id ) report_debug("Disabling "+moduleinfo->get_name()+" # "+id+"\n"); else report_debug("Disabling "+moduleinfo->get_name()+"\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); }
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  } destruct(me); return 1; } object|string find_module(string name) { 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 {
c5e0961999-10-04Per Hedbor  int wr; foreach (mods, string mod)
0ce25d1999-11-15Per Hedbor  if( ((now && !modules[ mod ]) || !enabled_modules[ mod+"#0" ] ) && !forcibly_added[ mod+"#0" ])
14179b1997-01-29Per Hedbor #ifdef MODULE_DEBUG {
c5e0961999-10-04Per Hedbor  if( !wr++ ) report_debug("[ adding required modules\n");
14179b1997-01-29Per Hedbor #endif
0ce25d1999-11-15Per Hedbor  forcibly_added[ mod+"#0" ] = 1; enable_module( mod+"#0" );
14179b1997-01-29Per Hedbor #ifdef MODULE_DEBUG }
c5e0961999-10-04Per Hedbor  if( wr ) report_debug("]\n");
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 = ([]); object sql_cache_get(string what) { #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 }
279a0c1997-11-26Henrik Grubbström (Grubba) object sql_connect(string db) {
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 + "/"; }
0f28da1997-08-13Per Hedbor void enable_all_modules()
14179b1997-01-29Per Hedbor {
c5e0961999-10-04Per Hedbor  enabled_modules = retrieve("EnabledModules", this_object()); array modules_to_process = indices( enabled_modules );
14179b1997-01-29Per Hedbor  string tmp_string;
44f2431999-06-07Martin Stjernholm  parse_log_formats(); init_log_file();
c5e0961999-10-04Per Hedbor  int start_time = gethrtime();
25171c1999-11-06Per Hedbor 
c5e0961999-10-04Per Hedbor  report_debug("\nEnabling all modules for "+query_name()+"... \n");
acfd171998-04-21Henrik Grubbström (Grubba) 
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 = (<>);
0f28da1997-08-13Per Hedbor  foreach( modules_to_process, tmp_string )
f5a2741999-10-18Per Hedbor  { if( !forcibly_added[ tmp_string ] ) if(err = catch( enable_module( tmp_string ))) report_error(LOCALE->enable_module_failed(tmp_string, describe_backtrace(err))); }
25171c1999-11-06Per Hedbor  report_debug("All modules for %s enabled in %3.1f seconds\n\n", query_name(),
c5e0961999-10-04Per Hedbor  (gethrtime()-start_time)/1000000.0);
0f28da1997-08-13Per Hedbor } void create(string config) {
f04e4f1999-04-22Per Hedbor  add_parse_module( this_object() );
14179b1997-01-29Per Hedbor  name=config;
c5e0961999-10-04Per Hedbor  report_debug("Creating virtual server '"+config+"'\n");
001ae71998-10-11Henrik Grubbström (Grubba) 
5d87801997-11-29Henrik Grubbström (Grubba)  defvar("ZNoSuchFile", "<title>Sorry. I cannot find this resource</title>\n" "<body bgcolor='#ffffff' text='#000000' alink='#ff0000' " "vlink='#00007f' link='#0000ff'>\n" "<h2 align=center><configimage src=roxen.gif alt=\"File not found\">\n"
14179b1997-01-29Per Hedbor  "<p><hr noshade>" "\n<i>Sorry</i></h2>\n"
45165f1997-08-13Peter Bortas  "<br clear>\n<font size=\"+2\">The resource requested "
14179b1997-01-29Per Hedbor  "<i>$File</i>\ncannot be found.<p>\n\nIf you feel that this is a " "configuration error, please contact "
5d87801997-11-29Henrik Grubbström (Grubba)  "the administrators or the author of the\n" "<if referrer>" "<a href=\"<referrer>\">referring</a>" "</if>\n" "<else>referring</else>\n" "page."
14179b1997-01-29Per Hedbor  "<p>\n</font>\n" "<hr noshade>"
5d87801997-11-29Henrik Grubbström (Grubba)  "<version>, at <a href=\"$Me\">$Me</a>.\n" "</body>\n",
14179b1997-01-29Per Hedbor  "Messages: No such file", TYPE_TEXT_FIELD, "What to return when there is no resource or file available " "at a certain location. $File will be replaced with the name " "of the resource requested, and $Me with the URL of this server ");
b796b51998-11-18Per 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
c5e0961999-10-04Per Hedbor  resursen, och '$Me' med serverns URL");
b796b51998-11-18Per Hedbor 
9b9f701997-08-12Per Hedbor  defvar("comment", "", "Virtual server comment", TYPE_TEXT_FIELD|VAR_MORE,
14179b1997-01-29Per Hedbor  "This text will be visible in the configuration interface, it " " can be quite useful to use as a memory helper.");
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 
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.");
14179b1997-01-29Per Hedbor  defvar("LogFormat", "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" , "Logging: Format",
9b9f701997-08-12Per Hedbor  TYPE_TEXT_FIELD|VAR_MORE,
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");});
b796b51998-11-18Per Hedbor  deflocaledoc("svenska", "LogFormat", "Loggning: Loggningsformat", #"Vilket format som ska användas för att logga <pre> svarskod eller *: Loggformat för svarskoden (eller alla koder som inte 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. $wchar(int) -- Stoppa in det tvåocktetstecken vars teckenkod är det angivna nummret. $int(int) -- Stoppa in det fyraocktetstecken vars teckenkod är det 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 binärdata i nätverksoktettordning $cern_date -- Ett datum som det ska vara enligt Cern Common Log file specifikationen $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 nätverksoktettordning. $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 '-' $user_id -- Ett unikt användarid. Tas från kakan RoxenUserID, du 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>");
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?");
14179b1997-01-29Per Hedbor  defvar("LogFile", roxen->QUERY(logdirprefix)+ short_name(name)+"/Log", "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" "%h Hour (e.g. '00')\n</pre>"
c5e0961999-10-04Per Hedbor  ,0, lambda(){ return !query("Log");});
b796b51998-11-18Per Hedbor  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>");
14179b1997-01-29Per Hedbor  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");});
b796b51998-11-18Per Hedbor  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.");
14179b1997-01-29Per Hedbor 
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"); deflocaledoc( "svenska", "Domain", "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.");
14179b1997-01-29Per Hedbor 
c5e0961999-10-04Per Hedbor  defvar("MyWorldLocation", "", "Server URL", TYPE_STRING, "This is the main server URL, where your start page is located.");
b796b51998-11-18Per Hedbor  deflocaledoc( "svenska", "MyWorldLocation", "Serverns URL",
c5e0961999-10-04Per Hedbor #"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  defvar("URLs", ({"http://*:80/"}), "URLs", TYPE_STRING_LIST, "Bind to these URLs" );
14179b1997-01-29Per Hedbor // This should be somewhere else, I think. Same goes for HTTP related ones
c5e0961999-10-04Per Hedbor // defvar("FTPWelcome", // " +-------------------------------------------------\n" // " +-- Welcome to the Roxen Challenger FTP server ---\n" // " +-------------------------------------------------\n", // "FTP: FTP Welcome", // TYPE_TEXT_FIELD|VAR_MORE, // "FTP Welcome answer; transmitted to new FTP connections if the file " // "<i>/welcome.msg</i> doesn't exist.\n"); // deflocaledoc("svenska", "FTPWelcome", // "FTP: Välkomstmeddelande", // #"Det här meddelanden skickas till alla FTP klienter så // fort de kopplar upp sig till servern"); // defvar("named_ftp", 0, "FTP: Allow named FTP", TYPE_FLAG|VAR_MORE, // "Allow ftp to normal user-accounts (requires an auth module, " // "e.g. 'User database and security').\n"); // deflocaledoc("svenska", "named_ftp", "FTP: Tillåt icke-anonym FTP", // "Tillåt FTP med loginnamn och lösenord. Du måste ha en " // " authentifikationsmodul för att kunna " // "använda icke-anonym FTP."); // defvar("anonymous_ftp", 1, "FTP: Allow anonymous FTP", TYPE_FLAG|VAR_MORE, // "Allows anonymous ftp.\n"); // deflocaledoc("svenska", "anonymous_ftp", "FTP: Tillåt anonym FTP", // "Tillåt anonym FTP"); // defvar("guest_ftp", 0, "FTP: Allow FTP guest users", TYPE_FLAG|VAR_MORE, // "Allows FTP guest users.\n"); // deflocaledoc( "svenska", "guest_ftp", // "FTP: Tillåt FTPgästanvändare", // "Tillåt FTPgästanvändare"); // defvar("ftp_user_session_limit", 0, // "FTP: User session limit", TYPE_INT|VAR_MORE, // "Limit of concurrent sessions a FTP user may have. 0 = unlimited.\n"); // deflocaledoc( "svenska", "ftp_user_session_limit", // "FTP: Maximalt antal samtidiga användarsessioner", // "0=obegränsat antal"); // defvar("shells", "/etc/shells", "FTP: Shell database", TYPE_FILE|VAR_MORE, // "File which contains a list of all valid shells\n" // "(usually /etc/shells). Used for named ftp.\n" // "Specify the empty string to disable shell database lookup.\n"); // deflocaledoc( "svenska", "shells", // "FTP: Skaldatabas", // #"En fil som innehåller en lista på alla tillåtna // skal. (normalt sett /etc/shells). Används för icke-anonym ftp. Ange // tomma strängen för att stänga av verifieringen av användarskal");
14179b1997-01-29Per Hedbor 
199d031999-09-05Francesco Chemolli  defvar("InternalLoc", "/_internal/",
5839c31999-01-22Marcus Comstedt  "Internal module resource mountpoint", TYPE_LOCATION|VAR_MORE, "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."); deflocaledoc("svenska", "InternalLoc", "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,
199d031999-09-05Francesco Chemolli #"If set, per-server bandwidth throttling will be enabled. It will allow you to limit the total available bandwidth for 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.
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle", "Bandviddsbegränsning: Servernivå: På", #"Om den här variablen är på så kommer bandvisddsbegränsning 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> Bandvidden räknas ut genom att använda en poletthink. Principen som den 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, #"This is the average bandwidth available to this Virtual Server in bytes/sec (the bucket \"fill rate\").", 0,arent_we_throttling_server);
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  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");
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);
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "throttle_min_grant", "Bandviddsbegränsning: Servernivå:" " Minimalt antal bytes", #"När det tillgängliga antalet poletter (alltså bytes) är mindre än det här 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);
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  deflocaledoc( "svenska", "req_throttle", "Bandviddsbegränsning: Förbindelsenivå: På", "Om på så begränsas bandvidden individuellt på förbindelser" );
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 combining a number of modules. But doing so can lead to too small or even negative bandwidths for particularly unlucky requests. This variable guarantees a minimum bandwidth for each request", 0,arent_we_throttling_request);
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "req_throttle_min", "Bandviddsbegränsning: Förbindelsenivå: Minimal bandvidd", #"Den maximala bandvidden som varje förbindelse får bestäms av en kombination av de bandviddsbegränsningsmoduler som är adderade i servern. Men ibland så blir det framräknade värdet väldigt lågt, och en del riktigt otursamma 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, #"The average bandwidth available for each request will be determined by the modules combination. The bucket depth will be determined multiplying the rate by this factor.", 0,arent_we_throttling_request);
4d16831999-11-17Per Hedbor  deflocaledoc( "svenska", "req_throttle_depth_mult", "Bandviddsbegränsning: Förbindelsenivå: Hinkstorlek", #"Den genomsnittliga bandvidden som varje förbindelse bestäms av de adderade bandvidsbegränsningsmodulerna. Hinkstorleken bestäms genom att multiplicera detta värde med den här faktorn.");
c5e0961999-10-04Per Hedbor  setvars(retrieve("spider#0", this_object()));
199d031999-09-05Francesco Chemolli 
c5e0961999-10-04Per Hedbor  if (query("throttle")) {
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+")"; }