df6cd11998-10-13Per Hedbor string cvs_version = "$Id: configuration.pike,v 1.161 1998/10/12 22:13:07 per Exp $";
b1fca01996-11-12Per Hedbor #include <module.h>
14179b1997-01-29Per Hedbor #include <roxen.h>
8afc811998-02-04Per Hedbor  #ifdef PROFILE mapping profile_map = ([]); #endif
18be211998-05-07Henrik Grubbström (Grubba) #define CATCH(X) do { mixed err; if(err = catch{X;}) report_error(describe_backtrace(err)); } while(0)
b461641998-10-11Henrik Grubbström (Grubba) // Locale support... #define LOCALE roxen->locale->base_server
18be211998-05-07Henrik Grubbström (Grubba) 
b1fca01996-11-12Per Hedbor /* A configuration.. */
1935351997-04-28Henrik Grubbström (Grubba) 
14179b1997-01-29Per Hedbor inherit "roxenlib";
3e44e61998-02-19Fredrik Noring public string real_file(string file, object id);
14179b1997-01-29Per Hedbor  function store = roxen->store; function retrieve = roxen->retrieve; function remove = roxen->remove; function do_dest = roxen->do_dest; function create_listen_socket = roxen->create_listen_socket;
b1fca01996-11-12Per Hedbor object parse_module; object types_module; object auth_module; object dir_module; function types_fun; function auth_fun; string name; /* Since the main module (Roxen, formerly Spinner, alias spider), does * not have any clones its settings must be stored somewhere else. * This looked like a likely spot.. :) */ mapping variables = ([]);
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 DEBUG_LEVEL > 30 perror(sprintf("MAIN: set(\"%s\", %O)\n", var, val)); #endif if(variables[var]) { #if DEBUG_LEVEL > 28 perror("MAIN: Setting global variable.\n"); #endif return variables[var][VAR_VALUE] = val; } error("set("+var+"). Unknown variable.\n"); } int setvars( mapping (string:mixed) vars ) { string v; // perror("Setting variables to %O\n", vars); foreach( indices( vars ), v ) if(variables[v]) variables[v][ VAR_VALUE ] = vars[ v ]; return 1; } void killvar(string name) { m_delete(variables, name); }
7acb8e1998-07-07Henrik Grubbström (Grubba) static class ConfigurableWrapper { int mode; function f; int check() { if ((mode & VAR_EXPERT) && (!roxen->configuration_interface()->expert_mode)) { return 1; } if ((mode & VAR_MORE) && (!roxen->configuration_interface()->more_mode)) { return 1; } return(f()); } void create(int mode_, function f_) { mode = mode_; f = f_; } };
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 { variables[var] = allocate( VAR_SIZE ); 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_TYPE_MASK; // Probably not needed, but... type &= (VAR_EXPERT | VAR_MORE); if (functionp(not_in_config)) { if (type) { variables[var][ VAR_CONFIGURABLE ] = ConfigurableWrapper(type, not_in_config)->check; } else { variables[var][ VAR_CONFIGURABLE ] = not_in_config; } } else if (type) { variables[var][ VAR_CONFIGURABLE ] = type; } else if(intp(not_in_config)) { variables[var][ VAR_CONFIGURABLE ] = !not_in_config; }
14179b1997-01-29Per Hedbor  variables[var][ VAR_SHORTNAME ] = var; }
df6cd11998-10-13Per Hedbor void deflocaledoc( string locale, string variable, string name, string doc ) { // Locale stuff! // Här blir vi farliga... if( !Locale.Roxen[locale] ) report_debug("Invalid locale: "+locale+". Ignoring.\n"); else Locale.Roxen[locale] ->register_module_doc( this_object(), variable, name, doc ); }
14179b1997-01-29Per Hedbor int definvisvar(string var, mixed value, int type) { return defvar(var, value, "", type, "", 0, 1); }
b1fca01996-11-12Per Hedbor  string query_name() { if(strlen(QUERY(name))) return QUERY(name); 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)) extension_modules = ([ ]); mapping (string:array(object)) file_extension_modules = ([ ]);
ae32d01998-03-23David Hedbor  mapping (object:multiset) provider_modules = ([ ]);
38dca81996-12-10Per Hedbor  void stop() {
b3c33c1998-05-08Henrik Grubbström (Grubba)  foreach(url_modules, object m) CATCH(m->stop && m->stop()); foreach(logger_modules, object m) CATCH(m->stop && m->stop()); foreach(filter_modules, object m) CATCH(m->stop && m->stop()); foreach(location_modules, object m) CATCH(m->stop && m->stop()); foreach(last_modules, object m) CATCH(m->stop && m->stop()); foreach(first_modules, object m) CATCH(m->stop && m->stop()); foreach(indices(provider_modules), object m) CATCH(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() { int a; array (object) tmp; tmp=allocate(10);
27b0e11996-11-26Per Hedbor  for(a=0; a<10; a++) tmp[a]=Priority();
b1fca01996-11-12Per Hedbor  return tmp; }
27b0e11996-11-26Per Hedbor class Bignum {
e8790b1998-02-19Per Hedbor #if constant(Gmp.mpz) // Perfect. :-) 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 int msb; int lsb=-0x7ffffffe;
b1fca01996-11-12Per Hedbor 
6e925d1996-12-02Per Hedbor  object `-(int i);
27b0e11996-11-26Per Hedbor  object `+(int i) {
14179b1997-01-29Per Hedbor  if(!i) return this_object();
6e925d1996-12-02Per Hedbor  if(i<0) return `-(-i);
14179b1997-01-29Per Hedbor  object res = object_program(this_object())(lsb+i,msb,2);
27b0e11996-11-26Per Hedbor  if(res->lsb < lsb) res->msb++; return res; }
b1fca01996-11-12Per Hedbor 
27b0e11996-11-26Per Hedbor  object `-(int i) {
14179b1997-01-29Per Hedbor  if(!i) return this_object();
6e925d1996-12-02Per Hedbor  if(i<0) return `+(-i);
14179b1997-01-29Per Hedbor  object res = object_program(this_object())(lsb-i,msb,2);
27b0e11996-11-26Per Hedbor  if(res->lsb > lsb) res->msb--; return res; }
b1fca01996-11-12Per Hedbor 
27b0e11996-11-26Per Hedbor  float mb() { return ((((float)lsb/1024.0/1024.0)+2048.0)+(msb*4096.0)); }
b1fca01996-11-12Per Hedbor 
f6d62d1997-03-26Per Hedbor  void create(int|void num, int|void bnum, int|void d)
27b0e11996-11-26Per Hedbor  { if(!d) lsb = num-0x7ffffffe; else lsb = num; msb = bnum; } #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 
14179b1997-01-29Per Hedbor object this = this_object();
b1fca01996-11-12Per Hedbor  // Used to store 'parser' modules before the main parser module // is added to the configuration. private object *_toparse_modules = ({}); // 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 = ([]); // A list of priority objects (used like a 'struct' in C, really) private array (object) pri = allocate_pris(); // All enabled modules in this virtual server. // The format is "module#copy":([ module_info ]) 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)) extension_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() {
3a4cea1998-05-09Henrik Grubbström (Grubba)  CATCH(parse_module && parse_module->stop && parse_module->stop()); CATCH(types_module && types_module->stop && types_module->stop()); CATCH(auth_module && auth_module->stop && auth_module->stop()); CATCH(dir_module && dir_module->stop && dir_module->stop()); for(int i=0; i<10; i++) CATCH(pri[i] && pri[i]->stop && pri[i]->stop());
38dca81996-12-10Per Hedbor }
c856841998-01-21Henrik Grubbström (Grubba) public string type_from_filename( string file, int|void to )
b1fca01996-11-12Per Hedbor {
14179b1997-01-29Per Hedbor  mixed tmp; object current_configuration; string ext=extension(file); if(!types_fun) return to?({ "application/octet-stream", 0 }):"application/octet-stream";
ad987b1998-02-24Per Hedbor // while(file[-1] == '/') // file = file[0..strlen(file)-2]; // Security patch?
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));
ae32d01998-03-23David Hedbor  if(arrayp(error))
9bb8131998-09-12Per Hedbor  roxen_perror(describe_backtrace(error+({ "Error in map_providers:"})));
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)) { return(ret); } })) { throw(error + ({ "Error in call_provider:"})); } }
ae32d01998-03-23David Hedbor  } }
14179b1997-01-29Per Hedbor 
b1fca01996-11-12Per Hedbor array (function) extension_modules(string ext, object id) { if(!extension_module_cache[ext]) { int i; extension_module_cache[ext] = ({ }); for(i=9; i>=0; i--) { object *d, p; if(d = pri[i]->extension_modules[ext]) foreach(d, p) extension_module_cache[ext] += ({ p->handle_extension }); } } return extension_module_cache[ext]; }
ae32d01998-03-23David 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 = ([]);
cf8aa81998-03-01David Hedbor mapping api_functions(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..]; return(0); } #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)
b1fca01996-11-12Per Hedbor  {
14179b1997-01-29Per Hedbor  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 {
8afc811998-02-04Per Hedbor #ifndef THREADS
b461641998-10-11Henrik Grubbström (Grubba)  object privs = Privs(LOCALE->opening_logfile(logfile));
8afc811998-02-04Per Hedbor #endif
f7d9811997-09-12Per Hedbor  object lf=open( logfile, "wac");
8afc811998-02-04Per Hedbor #if efun(chmod)
c79b261998-02-05Johan Schön #if efun(geteuid)
b5280a1998-04-09Henrik Grubbström (Grubba)  if(geteuid() != getuid()) catch {chmod(logfile,0666);};
c79b261998-02-05Johan Schön #endif
8afc811998-02-04Per Hedbor #endif
f7d9811997-09-12Per Hedbor  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; if(!log_function) return;// No file is open for logging. 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", "$bin-date", "$method", "$resource", "$protocol", "$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, http_encode_string((string)request_id->not_query), (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)
b461641998-10-11Henrik Grubbström (Grubba)  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) 
e911661997-08-29Henrik Grubbström (Grubba)  if ((roxen->configuration_interface()->more_mode) && (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 } // 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) return (["file":open("roxen-images/dir/"+from+".gif","r"), "type":"image/gif"]); } 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 ])) misc_cache[ a ] = seclevels = ({ function_object(a)->query_seclevels(),
85a2e51997-06-23Per Hedbor  function_object(a)->query("_seclvl"), function_object(a)->query("_sec_group")
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. return(1); }
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. return(0); } 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. return(0); } else { if (id->auth) { auth_ok |= 1; // Auth may be bad. } else { // No auth yet, get some. return(http_auth_failed(seclevels[2])); } } 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)));
18be211998-05-07Henrik Grubbström (Grubba)  return(1); }
12a9c51997-08-11Henrik Grubbström (Grubba)  if (ip_ok == 1) { // Bad IP. return(1); } else { // IP OK, or no IP restrictions. if (auth_ok == 1) { // Bad authentification. // Query for authentification. return(http_auth_failed(seclevels[2])); } else { // No auth required, or authentification OK. return(0); }
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; extension_module_cache = ([]); 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(); foreach(indices(otomod), object m) {
4bc6e31998-07-04Henrik Grubbström (Grubba)  if (m && m->clear_memory_caches) {
ec058c1998-07-04Henrik Grubbström (Grubba)  mixed err = catch { m->clear_memory_caches(); }; if (err) {
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) { 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  // changed 970820 by js to allow for jpeg images
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");
4154e61997-08-20Johan Schön  if(object f=open("roxen-images/"+from+".gif", "r")) return (["file":f,"type":"image/gif"]); else return (["file":open("roxen-images/"+from+".jpg", "r"),"type":"image/jpeg"]);
14179b1997-01-29Per 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. mapping (mixed:function|int) locks = ([]); public mapping|int get_file(object id, int|void no_magic); #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
41d0f91998-02-20Per Hedbor  #define TRACE_ENTER(A,B) do{if(id->misc->trace_enter)id->misc->trace_enter((A),(B));}while(0) #define TRACE_LEAVE(A) do{if(id->misc->trace_leave)id->misc->trace_leave((A));}while(0)
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(); 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; }
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;
41d0f91998-02-20Per Hedbor 
14179b1997-01-29Per Hedbor  if(!no_magic) { #ifndef NO_INTERNAL_HACK // No, this is not beautiful... :)
7b01a51998-05-18Henrik Grubbström (Grubba)  if(sizeof(file) && (file[0] == '/') && sscanf(file, "%*s/internal-%s", loc))
14179b1997-01-29Per Hedbor  { if(sscanf(loc, "gopher-%[^/]", loc)) // The directory icons.
41d0f91998-02-20Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->magic_internal_gopher());
14179b1997-01-29Per Hedbor  return internal_gopher_image(loc);
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  if(sscanf(loc, "spinner-%[^/]", loc) // Configuration interface images. ||sscanf(loc, "roxen-%[^/]", loc)) // Try /internal-roxen-power
41d0f91998-02-20Per Hedbor  {
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 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  } } // Well, this just _might_ be somewhat over-optimized, since it is // quite unreadable, but, you cannot win them all.. #ifdef URL_MODULES
f128901997-08-15Henrik Grubbström (Grubba)  // Map URL-modules
14179b1997-01-29Per Hedbor  foreach(url_modules(id), funp) { LOCK(funp);
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->url_module(), funp);
14179b1997-01-29Per Hedbor  tmp=funp( id, file ); UNLOCK();
f128901997-08-15Henrik Grubbström (Grubba)  if(mappingp(tmp))
41d0f91998-02-20Per Hedbor  { TRACE_LEAVE("");
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
f128901997-08-15Henrik Grubbström (Grubba)  return tmp;
41d0f91998-02-20Per Hedbor  }
f128901997-08-15Henrik Grubbström (Grubba)  if(objectp( tmp ))
14179b1997-01-29Per Hedbor  { array err; nest ++; err = catch { if( nest < 20 )
2dd1631997-08-06Marcus Comstedt  tmp = (id->conf || this_object())->low_get_file( tmp, no_magic );
14179b1997-01-29Per Hedbor  else
41d0f91998-02-20Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->too_deep_recursion());
14179b1997-01-29Per Hedbor  error("Too deep recursion in roxen::get_file() while mapping " +file+".\n");
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  }; nest = 0;
41d0f91998-02-20Per Hedbor  if(err) throw(err); TRACE_LEAVE("");
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
14179b1997-01-29Per Hedbor  return tmp; }
41d0f91998-02-20Per Hedbor  TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  } #endif #ifdef EXTENSION_MODULES if(tmp=extension_modules(loc=extension(file), id)) { foreach(tmp, funp) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->extension_module(loc), funp);
14179b1997-01-29Per Hedbor  LOCK(funp); tmp=funp(loc, id); UNLOCK(); if(tmp) { if(!objectp(tmp))
41d0f91998-02-20Per Hedbor  {
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  fid = tmp; #ifdef MODULE_LEVEL_SECURITY slevel = function_object(funp)->query("_seclvl");
41d0f91998-02-20Per Hedbor #endif
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_fd()
41d0f91998-02-20Per Hedbor #ifdef MODULE_LEVEL_SECURITY +(slevel != id->misc->seclevel?
b461641998-10-11Henrik Grubbström (Grubba)  LOCALE->seclevel_is_now(slevel):"")
41d0f91998-02-20Per Hedbor #endif ); #ifdef MODULE_LEVEL_SECURITY
28d38d1997-03-12Per Hedbor  id->misc->seclevel = slevel;
14179b1997-01-29Per Hedbor #endif break;
41d0f91998-02-20Per Hedbor  } else TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  } } #endif foreach(location_modules(id), tmp) { loc = tmp[0]; if(!search(file, loc)) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->location_module(loc), tmp[1]);
df8d711998-02-27Per Hedbor #ifdef MODULE_LEVEL_SECURITY
14179b1997-01-29Per Hedbor  if(tmp2 = check_security(tmp[1], id, slevel)) if(intp(tmp2)) {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->module_access_denied());
14179b1997-01-29Per Hedbor  continue; } else {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->request_denied());
14179b1997-01-29Per Hedbor  return tmp2; } #endif
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->calling_find_file(), 0);
14179b1997-01-29Per Hedbor  LOCK(tmp[1]);
a9268d1998-09-15Peter J. Holzer  fid=tmp[1]( file[ strlen(loc) .. ] + id->extra_extension, id);
14179b1997-01-29Per Hedbor  UNLOCK();
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->find_file_returned(fid));
14179b1997-01-29Per Hedbor  if(fid) { id->virtfile = loc;
b1fca01996-11-12Per Hedbor 
14179b1997-01-29Per Hedbor  if(mappingp(fid))
41d0f91998-02-20Per Hedbor  {
a1334f1998-02-20Mirar (Pontus Hagland)  TRACE_LEAVE(""); TRACE_LEAVE(examine_return_mapping(fid));
14179b1997-01-29Per Hedbor  return fid;
41d0f91998-02-20Per Hedbor  }
14179b1997-01-29Per Hedbor  else { #ifdef MODULE_LEVEL_SECURITY
df8d711998-02-27Per Hedbor  int oslevel = slevel;
9303ae1998-09-30Per Hedbor  slevel = misc_cache[ tmp[1] ][1]; // misc_cache from // check_security id->misc->seclevel = slevel;
14179b1997-01-29Per Hedbor #endif
41d0f91998-02-20Per Hedbor  if(objectp(fid))
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_fd()
41d0f91998-02-20Per Hedbor #ifdef MODULE_LEVEL_SECURITY +(slevel != oslevel?
b461641998-10-11Henrik Grubbström (Grubba)  LOCALE->seclevel_is_now(slevel):"")
41d0f91998-02-20Per Hedbor #endif +"."); else
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_directory_indicator()
41d0f91998-02-20Per Hedbor #ifdef MODULE_LEVEL_SECURITY +(oslevel != slevel?
b461641998-10-11Henrik Grubbström (Grubba)  LOCALE->seclevel_is_now(slevel):"")
41d0f91998-02-20Per Hedbor #endif );
14179b1997-01-29Per Hedbor  break; }
41d0f91998-02-20Per Hedbor  } else TRACE_LEAVE("");
14179b1997-01-29Per Hedbor  } else if(strlen(loc)-1==strlen(file)) { // This one is here to allow accesses to /local, even if // the mountpoint is /local/. It will slow things down, but... if(file+"/" == loc)
41d0f91998-02-20Per Hedbor  {
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->automatic_redirect_to_location(), tmp[1]); TRACE_LEAVE(LOCALE->returning_data());
14179b1997-01-29Per Hedbor  return http_redirect(id->not_query + "/", id);
41d0f91998-02-20Per 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... if(objectp(fid)&& (tmp=file_extension_modules(loc=extension(id->not_query), id))) 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) 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  } if(objectp(fid)) { if(stringp(id->extension)) id->not_query += id->extension;
41d0f91998-02-20Per Hedbor 
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->content_type_module(), types_module);
14179b1997-01-29Per Hedbor  tmp=type_from_filename(id->not_query, 1);
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)
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_not_found());
41d0f91998-02-20Per Hedbor  else
b461641998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_data());
14179b1997-01-29Per Hedbor  return fid; } 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);
14179b1997-01-29Per Hedbor  file=replace(file, "//", "/");
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  {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returning_list_files(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;
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
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;
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) {
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;
f920ce1998-10-02Henrik Grubbström (Grubba)  // FIXME: Shouldn't id->not_query be set to fname here? // grubba 1998-10-01
e8790b1998-02-19Per Hedbor  foreach(oc->first_modules(), funp) if(file = funp( id )) break; else if(id->conf != oc) { id->not_query = fname; 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; return ({ 0, file }); } if(file->data) { 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)  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 */
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_LEAVE(LOCALE->returned_mapping()); TRACE_LEAVE(LOCALE->empty_dir());
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)) {
001ae71998-10-11Henrik Grubbström (Grubba)  TRACE_ENTER(LOCALE->returned_mapping(), 0);
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) { return(c->stat_file(base + f, id)); }, 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
62eac81997-10-03Henrik Grubbström (Grubba)  // FIXME: NOTE: Limits filename length to 1000000 bytes. // /grubba 1997-10-03
14179b1997-01-29Per Hedbor  if(s=function_object(tmp[1])->real_file(file[strlen(loc)..1000000], id)) 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. public mixed try_get_file(string s, object id, int|void status, int|void nocache) { 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");
8223071998-04-26Mattias Wingstedt  if(!id->pragma["no-cache"] && !nocache)
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))
14179b1997-01-29Per Hedbor  fake_id->variables[http_decode_string(name)]=value; 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))) { fake_id->end(); return 0; } fake_id->end();
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;
14179b1997-01-29Per Hedbor #ifdef COMPAT if(m["string"]) res = m["string"]; // Compability..
d9624c1998-04-03Henrik Grubbström (Grubba)  else
14179b1997-01-29Per Hedbor #endif
d9624c1998-04-03Henrik Grubbström (Grubba)  if(m->data) res = m->data;
14179b1997-01-29Per Hedbor  else res=""; 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); } cache_set("file:"+id->conf->name, s, res); return res; } // Is 'what' a file in our virtual filesystem? public int is_file(string what, object id) { return !!stat_file(what, id); }
1260d31998-06-02Henrik Grubbström (Grubba) string MKPORTKEY(array(string) p) { if (sizeof(p[3])) { return(sprintf("%s://%s:%s/(%s)", p[1], p[2], (string)p[0], replace(p[3], ({"\n", "\r"}), ({ " ", " " })))); } else { return(sprintf("%s://%s:%s/", p[1], p[2], (string)p[0])); } } mapping(string:object) server_ports = ([]);
7b01a51998-05-18Henrik Grubbström (Grubba) 
4f4bc11998-02-04Per Hedbor int ports_changed = 1;
14179b1997-01-29Per Hedbor void start(int num) {
7b01a51998-05-18Henrik Grubbström (Grubba)  string server_name = query_name();
eb7a4f1997-08-25Henrik Grubbström (Grubba)  array port;
14179b1997-01-29Per Hedbor  int err=0; object lf; mapping new=([]), o2; parse_log_formats(); init_log_file();
4f4bc11998-02-04Per Hedbor 
7b01a51998-05-18Henrik Grubbström (Grubba) #if 0 // Doesn't seem to be set correctly. // /grubba 1998-05-18 if (!ports_changed) { return; } #endif /* 0 */ ports_changed = 0; // First find out if we have any new ports. mapping(string:array(string)) new_ports = ([]); foreach(query("Ports"), port) {
3ecb011998-07-07Henrik Grubbström (Grubba)  if ((< "ssl", "ssleay" >)[port[1]]) { // Obsolete versions of the SSL protocol.
001ae71998-10-11Henrik Grubbström (Grubba)  report_warning(server_name + ": " + LOCALE->obsolete_ssl(port[1]));
3ecb011998-07-07Henrik Grubbström (Grubba)  // Note: Change in-place. port[1] = "ssl3"; // FIXME: Should probably mark node as changed. }
7b01a51998-05-18Henrik Grubbström (Grubba)  string key = MKPORTKEY(port); if (!server_ports[key]) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_notice(LOCALE->new_port(server_name, key));
7b01a51998-05-18Henrik Grubbström (Grubba)  new_ports[key] = port; } else { // This is needed not to delete old unchanged ports. new_ports[key] = 0; } } // Then disable the old ones that are no more. foreach(indices(server_ports), string key) { if (zero_type(new_ports[key])) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_notice(LOCALE->disabling_port(server_name, key));
7b01a51998-05-18Henrik Grubbström (Grubba)  object o = server_ports[key]; m_delete(server_ports, key); mixed err; if (err = catch{ destruct(o); }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_warning(LOCALE->error_disabling_port(server_name, key, describe_backtrace(err)));
7b01a51998-05-18Henrik Grubbström (Grubba)  } o = 0; // Be sure that there are no references left... } } // Now we can create the new ports.
001ae71998-10-11Henrik Grubbström (Grubba)  roxen_perror(LOCALE->opening_ports(server_name));
7b01a51998-05-18Henrik Grubbström (Grubba)  foreach(indices(new_ports), string key) { port = new_ports[key]; if (port) {
4f4bc11998-02-04Per Hedbor  array old = port; mixed erro; erro = catch {
7b01a51998-05-18Henrik Grubbström (Grubba)  program requestprogram = (program)(getcwd()+"/protocols/"+port[1]); function rp; array tmp; if(!requestprogram) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(server_name + ": " + LOCALE->no_request_program(port[1]));
7b01a51998-05-18Henrik Grubbström (Grubba)  continue; } if(rp = requestprogram()->real_port) if(tmp = rp(port, this_object())) port = tmp; // FIXME: For SSL3 we might need to be root to read our // secret files. object privs; if(port[0] < 1024)
001ae71998-10-11Henrik Grubbström (Grubba)  privs = Privs(LOCALE->opening_low_port());
7b01a51998-05-18Henrik Grubbström (Grubba)  object o; if(o=create_listen_socket(port[0], this_object(), port[2], requestprogram, port)) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_notice(LOCALE->opening_port(server_name, key));
7b01a51998-05-18Henrik Grubbström (Grubba)  server_ports[key] = o; } else {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->could_not_open_port(server_name, key));
7b01a51998-05-18Henrik Grubbström (Grubba)  }
ddf7e61998-02-24Henrik Grubbström (Grubba)  if (privs) { destruct(privs); // Paranoia. }
4f4bc11998-02-04Per Hedbor  };
7b01a51998-05-18Henrik Grubbström (Grubba)  if (erro) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->failed_to_open_port(server_name, key, (stringp(erro)?erro: describe_backtrace(erro))));
eb7a4f1997-08-25Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor  } }
7b01a51998-05-18Henrik Grubbström (Grubba)  if (sizeof(query("Ports")) && !sizeof(server_ports)) {
001ae71998-10-11Henrik Grubbström (Grubba)  string port_list = Array.map(query("Ports"), lambda(array p) { return sprintf("%5d %-10s %-20s\n", @p); })*""; report_error(LOCALE->no_ports_available_tried(name, port_list));
14179b1997-01-29Per Hedbor  } } // Save this configuration. If all is included, save all configuration // global variables as well, otherwise only all module variables. void save(int|void all) { mapping mod; if(all) { store("spider.lpc#0", variables, 0, this); start(2); } foreach(values(modules), mod) { if(mod->enabled) { store(mod->sname+"#0", mod->master->query(), 0, this); mod->enabled->start(2, this); } else if(mod->copies) { int i; foreach(indices(mod->copies), i) { store(mod->sname+"#"+i, mod->copies[i]->query(), 0, this); mod->copies[i]->start(2, this); } } }
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) { store("spider#0", variables, 0, this); start(2); return 1; } foreach(values(modules), mod) { if( mod->enabled == o) { store(mod->sname+"#0", o->query(), 0, this); o->start(2, this);
8cc31b1997-10-12Henrik Grubbström (Grubba)  invalidate_cache();
14179b1997-01-29Per Hedbor  return 1; } else if(mod->copies) { int i; foreach(indices(mod->copies), i) { if(mod->copies[i] == o) { store(mod->sname+"#"+i, o->query(), 0, this); o->start(2, this);
8cc31b1997-10-12Henrik Grubbström (Grubba)  invalidate_cache();
14179b1997-01-29Per Hedbor  return 1; } } } } } mapping _hooks=([ ]); void hooks_for( string modname, object mod ) { array hook; if(_hooks[modname]) { #ifdef MODULE_DEBUG perror("Module hooks..."); #endif foreach(_hooks[modname], hook) hook[0]( @hook[1], mod ); } } int unload_module( string modname ); int load_module( string modname ); object enable_module( string modname ) { string id; mapping module; mapping enabled_modules; roxen->current_configuration = this_object(); modname = replace(modname, ".lpc#","#"); sscanf(modname, "%s#%s", modname, id ); module = modules[ modname ]; if(!module) { load_module(modname); module = modules[ modname ]; }
ae32d01998-03-23David Hedbor #if constant(gethrtime)
7f00081998-03-20Per Hedbor  int start_time = gethrtime();
ae32d01998-03-23David Hedbor #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  if (!module) { return 0; } object me; mapping tmp; int pr; array err;
14179b1997-01-29Per Hedbor  #ifdef MODULE_DEBUG
ad683e1998-05-09Henrik Grubbström (Grubba)  perror("Enabling "+module->name+" # "+id+" ... ");
14179b1997-01-29Per Hedbor #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->copies) { if (err = catch(me = module["program"]())) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->could_not_clone_module(module->name, describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  if (module->copies[id]) {
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
ad683e1998-05-09Henrik Grubbström (Grubba)  perror("Keeping old copy\n");
3bbda81997-06-11Henrik Grubbström (Grubba) #endif }
ad683e1998-05-09Henrik Grubbström (Grubba)  return(module->copies[id]); } if(module->copies[id]) {
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
ad683e1998-05-09Henrik Grubbström (Grubba)  perror("Disabling old copy ... ");
3bbda81997-06-11Henrik Grubbström (Grubba) #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  if (err = catch{ module->copies[id]->stop(); }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->error_disabling_module(module->name, describe_backtrace(err)));
14179b1997-01-29Per Hedbor  }
ad683e1998-05-09Henrik Grubbström (Grubba)  destruct(module->copies[id]); } } else { if(objectp(module->master)) { me = module->master;
14179b1997-01-29Per Hedbor  } else {
ad683e1998-05-09Henrik Grubbström (Grubba)  if (err = catch(me = module["program"]())) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->could_not_clone_module(module->name, describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  return(0);
3bbda81997-06-11Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor  }
ad683e1998-05-09Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor 
3bbda81997-06-11Henrik Grubbström (Grubba) #ifdef MODULE_DEBUG
ad683e1998-05-09Henrik Grubbström (Grubba)  // perror("Initializing ");
3bbda81997-06-11Henrik Grubbström (Grubba) #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  if (module->type & (MODULE_LOCATION | MODULE_EXTENSION | MODULE_FILE_EXTENSION | MODULE_LOGGER | MODULE_URL | MODULE_LAST | MODULE_PROVIDER | MODULE_FILTER | MODULE_PARSER | MODULE_FIRST)) {
001ae71998-10-11Henrik Grubbström (Grubba)  // FIXME: LOCALIZE!
ad683e1998-05-09Henrik Grubbström (Grubba)  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}));
df6cd11998-10-13Per Hedbor  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 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type != MODULE_LOGGER && module->type != MODULE_PROVIDER) { 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" "lösenordsdialogen.");
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>.");
14179b1997-01-29Per Hedbor 
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" " or auth-module. The default (used when _no_ " "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.");
14179b1997-01-29Per Hedbor 
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" " or 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, "An optional name. Set to something to remaind you what " "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.");
ad683e1998-05-09Henrik Grubbström (Grubba)  me->setvars(retrieve(modname + "#" + id, this));
33e6351998-02-28Martin Stjernholm 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->copies) module->copies[(int)id] = me; else module->enabled = me;
33e6351998-02-28Martin Stjernholm 
ad683e1998-05-09Henrik Grubbström (Grubba)  otomod[ me ] = modname;
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  mixed err; if((me->start) && (err = catch{ me->start(0, this); })) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  /* Clean up some broken references to this module. */ m_delete(otomod, me); if(module->copies) m_delete(module->copies, (int)id); else m_delete(module, "enabled"); destruct(me); return 0; } if (err = catch(pr = me->query("_priority"))) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  pr = 3; } api_module_cache |= me->api_functions(); if(module->type & MODULE_EXTENSION) { if (err = catch { array arr = me->query_extensions(); if (arrayp(arr)) { string foo; foreach( arr, foo ) if(pri[pr]->extension_modules[ foo ]) pri[pr]->extension_modules[foo] += ({ me }); else pri[pr]->extension_modules[foo] = ({ me }); } }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
14179b1997-01-29Per Hedbor  }
ad683e1998-05-09Henrik Grubbström (Grubba)  } if(module->type & MODULE_FILE_EXTENSION) { if (err = catch { array arr = me->query_file_extensions(); if (arrayp(arr)) { 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}); } }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
3bbda81997-06-11Henrik Grubbström (Grubba)  }
ad683e1998-05-09Henrik Grubbström (Grubba)  }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_PROVIDER) { if (err = catch { 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)  }
ad683e1998-05-09Henrik Grubbström (Grubba)  }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
14179b1997-01-29Per Hedbor  }
ad683e1998-05-09Henrik Grubbström (Grubba)  } if(module->type & MODULE_TYPES) { types_module = me; types_fun = me->type_from_extension; } if((module->type & MODULE_MAIN_PARSER)) { parse_module = me; if (_toparse_modules) { Array.map(_toparse_modules, lambda(object o, object me, mapping module) { array err; if (err = catch { me->add_parse_module(o); }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
ad683e1998-05-09Henrik Grubbström (Grubba)  } }, me, module); } }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_PARSER) { if(parse_module) {
ae32d01998-03-23David Hedbor  if (err = catch {
ad683e1998-05-09Henrik Grubbström (Grubba)  parse_module->add_parse_module( me );
ae32d01998-03-23David Hedbor  }) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> error_initializing_module_copy(module->name, describe_backtrace(err)));
ae32d01998-03-23David Hedbor  } }
ad683e1998-05-09Henrik Grubbström (Grubba)  _toparse_modules += ({ me }); }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_AUTH) { auth_module = me; auth_fun = me->auth; }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_DIRECTORIES) dir_module = me;
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_LOCATION) pri[pr]->location_modules += ({ me });
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_LOGGER) pri[pr]->logger_modules += ({ me });
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_URL) pri[pr]->url_modules += ({ me });
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_LAST) pri[pr]->last_modules += ({ me });
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_FILTER) pri[pr]->filter_modules += ({ me });
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(module->type & MODULE_FIRST) { pri[pr]->first_modules += ({ me }); }
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  hooks_for(module->sname+"#"+id, me);
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  enabled_modules=retrieve("EnabledModules", this);
14179b1997-01-29Per Hedbor 
ad683e1998-05-09Henrik Grubbström (Grubba)  if(!enabled_modules[modname+"#"+id]) {
14179b1997-01-29Per Hedbor #ifdef MODULE_DEBUG
ad683e1998-05-09Henrik Grubbström (Grubba)  perror("New module...");
14179b1997-01-29Per Hedbor #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  enabled_modules[modname+"#"+id] = 1; store( "EnabledModules", enabled_modules, 1, this); } invalidate_cache();
7f00081998-03-20Per Hedbor #ifdef MODULE_DEBUG
ae32d01998-03-23David Hedbor #if constant(gethrtime)
7f00081998-03-20Per Hedbor  perror(" Done (%3.3f seconds).\n", (gethrtime()-start_time)/1000000.0); #else perror(" Done.\n"); #endif #endif
ad683e1998-05-09Henrik Grubbström (Grubba)  return me;
14179b1997-01-29Per Hedbor } // Called from the configuration interface. string check_variable(string name, string value) { switch(name) {
4f4bc11998-02-04Per Hedbor  case "Ports": ports_changed=1; return 0;
14179b1997-01-29Per Hedbor  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;
14179b1997-01-29Per Hedbor  } } // This is used to update the server-global and module variables // between Roxen releases. It enables the poor roxen administrator to // reuse the configuration file from a previous release. without any // fuss. Configuration files from Roxen 1.0ß11 pre 11 and earlier // are not differentiated, but since that release is quite old already // when I write this, that is not really a problem.... #define perr(X) do { report += X; perror(X); } while(0) // Used to hide some variables when logging is not enabled. int log_is_not_enabled() { return !query("Log"); }
1e5ee81997-08-21Per Hedbor  // Get the current domain. This is not as easy as one could think.
14179b1997-01-29Per Hedbor private string get_domain(int|void l) { array f; string t, s; // ConfigurationURL is set by the 'install' script.
ef7af21997-09-05Henrik Grubbström (Grubba)  if (!l) { f = (roxen->QUERY(ConfigurationURL)/"://"); if (sizeof(f) > 1) { t = (replace(f[1], ({ ":", "/" }), ({ "\0", "\0" }))/"\0")[0]; f = t/"."; if (sizeof(f) > 1) { s = f[1..]*"."; } } }
c79b261998-02-05Johan Schön #if efun(gethostbyname) #if efun(gethostname)
ef7af21997-09-05Henrik Grubbström (Grubba)  if(!s) {
14179b1997-01-29Per Hedbor  f = gethostbyname(gethostname()); // First try.. if(f)
ef7af21997-09-05Henrik Grubbström (Grubba)  foreach(f, f) { if (arrayp(f)) { foreach(f, t) { f = t/"."; if ((sizeof(f) > 1) && (replace(t, ({ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "." }), ({ "","","","","","","","","","","" })) != "")) { t = f[1..]*"."; if(!s || strlen(s) < strlen(t)) s=t; } } }
14179b1997-01-29Per Hedbor  }
ef7af21997-09-05Henrik Grubbström (Grubba)  }
c79b261998-02-05Johan Schön #endif
ef7af21997-09-05Henrik Grubbström (Grubba) #endif if(!s) { t = Stdio.read_bytes("/etc/resolv.conf"); if(t) { if(!sscanf(t, "domain %s\n", s)) if(!sscanf(t, "search %s%*[ \t\n]", s)) s="nowhere";
3d4b711997-09-05Henrik Grubbström (Grubba)  } else {
ef7af21997-09-05Henrik Grubbström (Grubba)  s="nowhere";
14179b1997-01-29Per Hedbor  } } if(s && strlen(s)) { if(s[-1] == '.') s=s[..strlen(s)-2]; if(s[0] == '.') s=s[1..]; } else { s="unknown"; } return s; } int disable_module( string modname ) { mapping module; mapping enabled_modules; object me; int pr; int id; sscanf(modname, "%s#%d", modname, id ); module = modules[ modname ]; if(!module) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->disable_nonexistant_module(modname));
14179b1997-01-29Per Hedbor  return 0; } if(module->copies) { me = module->copies[id]; m_delete(module->copies, id); if(!sizeof(module->copies)) unload_module(modname); } else { me = module->enabled || module->master; module->enabled=module->master = 0; unload_module(modname); }
8cc31b1997-10-12Henrik Grubbström (Grubba)  invalidate_cache();
14179b1997-01-29Per Hedbor  if(!me) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->disable_module_failed(module->name+" # "+id));
14179b1997-01-29Per Hedbor  return 0; } if(me->stop) me->stop(); #ifdef MODULE_DEBUG
7f00081998-03-20Per Hedbor  perror("Disabling "+module->name+" # "+id+"\n");
14179b1997-01-29Per Hedbor #endif if(module["type"] & MODULE_EXTENSION && arrayp( me -> query_extensions())) { string foo; foreach( me -> query_extensions(), foo ) for(pr=0; pr<10; pr++) if( pri[pr]->extension_modules[ foo ] ) pri[pr]->extension_modules[ foo ]-= ({ me }); } if(module["type"] & MODULE_FILE_EXTENSION && arrayp( me -> query_file_extensions())) { string foo; foreach( me -> query_file_extensions(), foo ) for(pr=0; pr<10; pr++) if(pri[pr]->file_extension_modules[ foo ] ) pri[pr]->file_extension_modules[foo]-=({me}); }
ae32d01998-03-23David Hedbor  if(module->type & MODULE_PROVIDER) { for(pr=0; pr<10; pr++) m_delete(pri[pr]->provider_modules, me); }
14179b1997-01-29Per Hedbor  if(module["type"] & MODULE_TYPES) { types_module = 0; types_fun = 0; } if(module->type & MODULE_MAIN_PARSER) parse_module = 0; if(module->type & MODULE_PARSER) { if(parse_module) parse_module->remove_parse_module( me ); _toparse_modules -= ({ me, 0 }); } if( module->type & MODULE_AUTH ) { auth_module = 0; auth_fun = 0; } if( module->type & MODULE_DIRECTORIES ) dir_module = 0; if( module->type & MODULE_LOCATION ) for(pr=0; pr<10; pr++) pri[pr]->location_modules -= ({ me }); if( module->type & MODULE_URL ) for(pr=0; pr<10; pr++) pri[pr]->url_modules -= ({ me }); if( module->type & MODULE_LAST ) for(pr=0; pr<10; pr++) pri[pr]->last_modules -= ({ me }); if( module->type & MODULE_FILTER ) for(pr=0; pr<10; pr++) pri[pr]->filter_modules -= ({ me });
f128901997-08-15Henrik Grubbström (Grubba)  if( module->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  if( module->type & MODULE_LOGGER ) for(pr=0; pr<10; pr++) pri[pr]->logger_modules -= ({ me }); enabled_modules=retrieve("EnabledModules", this); if(enabled_modules[modname+"#"+id]) { m_delete( enabled_modules, modname + "#" + id ); store( "EnabledModules",enabled_modules, 1, this); } destruct(me); return 1; } object|string find_module(string name) { int id; sscanf(name, "%s#%d", name, id); if(modules[name]) { if(modules[name]->copies) return modules[name]->copies[id]; else if(modules[name]->enabled) return modules[name]->enabled; } return 0; } void register_module_load_hook( string modname, function fun, mixed ... args ) { object o; #ifdef MODULE_DEBUG perror("Registering a hook for the module "+modname+"\n"); #endif if(o=find_module(modname)) { #ifdef MODULE_DEBUG perror("Already there!\n"); #endif fun( @args, o ); } else if(!_hooks[modname]) _hooks[modname] = ({ ({ fun, args }) }); else _hooks[modname] += ({ ({ fun, args }) }); } int load_module(string module_file) { int foo, disablep; mixed err; mixed *module_data; mapping loaded_modules; object obj; program prog;
7f00081998-03-20Per Hedbor #if efun(gethrtime) int start_time = gethrtime(); #endif
8c62221997-08-06Henrik Grubbström (Grubba)  // It is not thread-safe to use this.
14179b1997-01-29Per Hedbor  roxen->current_configuration = this_object(); #ifdef MODULE_DEBUG
7f00081998-03-20Per Hedbor  perror("\nLoading " + module_file + "... ");
14179b1997-01-29Per Hedbor #endif
246cff1997-07-16Henrik Grubbström (Grubba)  if(prog=cache_lookup("modules", module_file)) { err = catch {
36086b1997-08-07Mirar (Pontus Hagland)  obj = prog(this_object());
246cff1997-07-16Henrik Grubbström (Grubba)  }; } else {
14179b1997-01-29Per Hedbor  string dir;
6193221997-05-31Henrik Grubbström (Grubba)  _master->set_inhibit_compile_errors("");
14179b1997-01-29Per Hedbor 
246cff1997-07-16Henrik Grubbström (Grubba)  err = catch {
8c62221997-08-06Henrik Grubbström (Grubba)  obj = roxen->load_from_dirs(roxen->QUERY(ModuleDirs), module_file, this_object());
246cff1997-07-16Henrik Grubbström (Grubba)  };
14179b1997-01-29Per Hedbor 
7f00081998-03-20Per Hedbor  string errors = (string)_master->errors;
6193221997-05-31Henrik Grubbström (Grubba) 
246cff1997-07-16Henrik Grubbström (Grubba)  _master->set_inhibit_compile_errors(0); if (sizeof(errors)) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->module_compilation_errors(module_file, errors));
246cff1997-07-16Henrik Grubbström (Grubba)  return(0);
14179b1997-01-29Per Hedbor  } prog = roxen->last_loaded(); }
246cff1997-07-16Henrik Grubbström (Grubba)  if (err) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->error_enabling_module(module_file, describe_backtrace(err)));
246cff1997-07-16Henrik Grubbström (Grubba)  return(0); }
14179b1997-01-29Per Hedbor  if(!obj) {
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->module_load_failed(module_file));
14179b1997-01-29Per Hedbor  return 0; }
09497b1997-08-18Henrik Grubbström (Grubba)  if (err = catch (module_data = obj->register_module(this_object()))) {
14179b1997-01-29Per Hedbor #ifdef MODULE_DEBUG perror("FAILED\n" + describe_backtrace( err )); #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE-> module_loaded_register_module_failed(module_file, describe_backtrace(err)));
14179b1997-01-29Per Hedbor  return 0; } err = "";
e493e81997-07-11Per Hedbor  roxen->somemodules[module_file]= ({ module_data[1], module_data[2]+"<p><i>"+ replace(obj->file_name_and_stuff(),"0<br>", module_file+"<br>") +"</i>", module_data[0] });
14179b1997-01-29Per Hedbor  if (!arrayp( module_data ))
001ae71998-10-11Henrik Grubbström (Grubba)  err = LOCALE->bad_register_module_result();
14179b1997-01-29Per Hedbor  else switch (sizeof( module_data )) { case 5:
57fbf21997-07-31Marcus Comstedt  foo=module_data[4];
14179b1997-01-29Per Hedbor  module_data=module_data[0..3]; case 4: if (module_data[3] && !arrayp( module_data[3] ))
001ae71998-10-11Henrik Grubbström (Grubba)  err = LOCALE->bad_register_module4() + err;
14179b1997-01-29Per Hedbor  case 3: if (!stringp( module_data[2] ))
001ae71998-10-11Henrik Grubbström (Grubba)  err = LOCALE->bad_register_module3() + err;
14179b1997-01-29Per Hedbor  if (!stringp( module_data[1] ))
001ae71998-10-11Henrik Grubbström (Grubba)  err = LOCALE->bad_register_module2() + err;
14179b1997-01-29Per Hedbor  if (!intp( module_data[0] ))
001ae71998-10-11Henrik Grubbström (Grubba)  err = LOCALE->bad_register_module1() + err;
14179b1997-01-29Per Hedbor  break;
001ae71998-10-11Henrik Grubbström (Grubba)  default: err = LOCALE->bad_register_module_other();
14179b1997-01-29Per Hedbor  } if (err != "") { #ifdef MODULE_DEBUG perror("FAILED\n"+err); #endif
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->tried_moding_module(module_file, err));
14179b1997-01-29Per Hedbor  if(obj) destruct( obj ); return 0; } if (sizeof(module_data) == 3) module_data += ({ 0 }); if(!foo) { destruct(obj); obj=0; } else { otomod[obj] = module_file; } if(!modules[ module_file ]) modules[ module_file ] = ([]); mapping tmpp = modules[ module_file ]; tmpp->type=module_data[0]; tmpp->name=module_data[1]; tmpp->doc=module_data[2]; tmpp->extra=module_data[3]; tmpp["program"]=prog; tmpp->master=obj; tmpp->copies=(foo ? 0 : (tmpp->copies||([]))); tmpp->sname=module_file; #ifdef MODULE_DEBUG
7f00081998-03-20Per Hedbor #if efun(gethrtime) perror(" Done (%3.3f seconds).\n", (gethrtime()-start_time)/1000000.0); #else perror(" Done.\n"); #endif
14179b1997-01-29Per Hedbor #endif cache_set("modules", module_file, modules[module_file]["program"]);
8cc31b1997-10-12Henrik Grubbström (Grubba) // ?? invalidate_cache();
14179b1997-01-29Per Hedbor  return 1; } int unload_module(string module_file) { mapping module; int id; module = modules[ module_file ]; if(!module) return 0; if(objectp(module->master)) destruct(module->master); cache_remove("modules", module_file); m_delete(modules, module_file); return 1; } int port_open(array prt) {
7b01a51998-05-18Henrik Grubbström (Grubba)  return(server_ports[MKPORTKEY(prt)] != 0);
14179b1997-01-29Per Hedbor } string desc() { string res=""; array (string|int) port;
953ca31997-08-18Per Hedbor  if(!sizeof(QUERY(Ports))) {
d24d291997-08-19Per Hedbor /* array ips = roxen->configuration_interface()->ip_number_list;*/ /* if(!ips) roxen->configuration_interface()->init_ip_list;*/ /* ips = roxen->configuration_interface()->ip_number_list;*/ /* foreach(ips||({}), string ip)*/ /* {*/ /* }*/ array handlers = ({}); foreach(roxen->configurations, object c) if(c->modules["ip-less_hosts"]) handlers+=({({http_encode_string("/Configurations/"+c->name), strlen(c->query("name"))?c->query("name"):c->name})}); if(sizeof(handlers)==1) {
001ae71998-10-11Henrik Grubbström (Grubba)  res = LOCALE->server_ports_handled_by_one(handlers[0][0], handlers[0][1]);
d24d291997-08-19Per Hedbor  } else if(sizeof(handlers)) {
001ae71998-10-11Henrik Grubbström (Grubba)  string serverlist = "";
d24d291997-08-19Per Hedbor  foreach(handlers, array h)
001ae71998-10-11Henrik Grubbström (Grubba)  serverlist += "<a href=\""+h[0]+"\">"+h[1]+"</a><br>\n"; res = LOCALE->server_ports_handled_by_multiple(serverlist);
d24d291997-08-19Per Hedbor  } else
001ae71998-10-11Henrik Grubbström (Grubba)  res = LOCALE->server_ports_handled_by_none();
953ca31997-08-18Per Hedbor  }
14179b1997-01-29Per Hedbor  foreach(QUERY(Ports), port) { string prt;
9f46de1997-04-08Per Hedbor  switch(port[1][0..2])
14179b1997-01-29Per Hedbor  { case "ssl": prt = "https://"; break;
4ba6fc1998-04-03Henrik Grubbström (Grubba)  case "ftp": prt = "ftp://"; break;
14179b1997-01-29Per Hedbor  default: prt = port[1]+"://"; } if(port[2] && port[2]!="ANY") prt += port[2]; else
c79b261998-02-05Johan Schön #if efun(gethostname)
14179b1997-01-29Per Hedbor  prt += (gethostname()/".")[0] + "." + QUERY(Domain);
c79b261998-02-05Johan Schön #else ; #endif
0f28da1997-08-13Per Hedbor  prt += ":"+port[0]+"/";
14179b1997-01-29Per Hedbor  if(port_open( port ))
001ae71998-10-11Henrik Grubbström (Grubba)  res += LOCALE->server_port_open(prt);
14179b1997-01-29Per Hedbor  else
001ae71998-10-11Henrik Grubbström (Grubba)  res += LOCALE->server_port_not_open(prt);
14179b1997-01-29Per Hedbor  }
001ae71998-10-11Henrik Grubbström (Grubba)  return (res + LOCALE->server_url(query("MyWorldLocation")) + "<p>");
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 !constant(this_thread) return Sql.sql( what ); #else 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() ]; #endif /* !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) { if (sql_urls[db]) {
ed93131998-07-09Johan Schön  return(sql_cache_get(sql_urls[db]));
279a0c1997-11-26Henrik Grubbström (Grubba)  } else {
ed93131998-07-09Johan Schön  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 {
7f00081998-03-20Per Hedbor #if efun(gethrtime) int start_time = gethrtime(); #endif
1e5ee81997-08-21Per Hedbor  array modules_to_process=sort(indices(retrieve("EnabledModules",this)));
14179b1997-01-29Per Hedbor  string tmp_string;
ce4ac81997-09-08David Hedbor  perror("\nEnabling all modules for "+query_name()+"... \n");
acfd171998-04-21Henrik Grubbström (Grubba)  #if constant(_compiler_trace) // _compiler_trace(1); #endif /* !constant(_compiler_trace) */
ce4ac81997-09-08David Hedbor 
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; foreach( modules_to_process, tmp_string ) if(err = catch( enable_module( tmp_string ) ))
001ae71998-10-11Henrik Grubbström (Grubba)  report_error(LOCALE->enable_module_failed(tmp_string, describe_backtrace(err)));
0f28da1997-08-13Per Hedbor  roxen->current_configuration = 0;
7f00081998-03-20Per Hedbor #if efun(gethrtime) perror("\nAll modules for %s enabled in %4.3f seconds\n\n", query_name(), (gethrtime()-start_time)/1000000.0); #endif
0f28da1997-08-13Per Hedbor } void create(string config) {
14179b1997-01-29Per Hedbor  roxen->current_configuration = this; name=config;
ce4ac81997-09-08David Hedbor  perror("Creating virtual server '"+config+"'\n");
14179b1997-01-29Per Hedbor 
001ae71998-10-11Henrik Grubbström (Grubba)  // FIXME: LOCALIZE!
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 ");
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.");
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"); 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" "$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" "</pre>", 0, log_is_not_enabled); defvar("Log", 1, "Logging: Enabled", TYPE_FLAG, "Log requests"); 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>" "%y Year (i.e. '1997')\n" "%m Month (i.e. '08')\n" "%d Date (i.e. '10' for the tenth)\n" "%h Hour (i.e. '00')\n</pre>" ,0, log_is_not_enabled);
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 " "log.\n",0, log_is_not_enabled);
1e5ee81997-08-21Per Hedbor  defvar("Domain", get_domain(), "Domain", TYPE_STRING,
14179b1997-01-29Per Hedbor  "Your domainname, should be set automatically, if not, "
3d4b711997-09-05Henrik Grubbström (Grubba)  "enter the correct domain name here, and send a bug report to "
0247a31998-03-11David Hedbor  "<a href=\"mailto:roxen-bugs@idonex.se\">roxen-bugs@idonex.se"
14179b1997-01-29Per Hedbor  "</a>");
1e5ee81997-08-21Per Hedbor  defvar("Ports", ({ }),
14179b1997-01-29Per Hedbor  "Listen ports", TYPE_PORTS, "The ports this virtual instance of Roxen will bind to.\n"); defvar("MyWorldLocation", get_my_url(), "Server URL", TYPE_STRING, "This is where your start page is located."); // This should be somewhere else, I think. Same goes for HTTP related ones defvar("FTPWelcome", " +-------------------------------------------------\n" " +-- Welcome to the Roxen Challenger FTP server ---\n" " +-------------------------------------------------\n", "Messages: FTP Welcome",
9b9f701997-08-12Per Hedbor  TYPE_TEXT_FIELD|VAR_MORE,
14179b1997-01-29Per Hedbor  "FTP Welcome answer; transmitted to new FTP connections if the file " "<i>/welcome.msg</i> doesn't exist.\n");
9b9f701997-08-12Per Hedbor  defvar("named_ftp", 0, "Allow named FTP", TYPE_FLAG|VAR_MORE,
de37d31997-04-09Marcus Comstedt  "Allow ftp to normal user-accounts (requires auth-module).\n");
a0a52b1997-08-23Henrik Grubbström (Grubba)  defvar("anonymous_ftp", 1, "Allow anonymous FTP", TYPE_FLAG|VAR_MORE,
3d4b711997-09-05Henrik Grubbström (Grubba)  "Allows anonymous ftp.\n");
a0a52b1997-08-23Henrik Grubbström (Grubba) 
d9aa7c1998-03-27Henrik Grubbström (Grubba)  defvar("guest_ftp", 0, "Allow FTP guest users", TYPE_FLAG|VAR_MORE, "Allows FTP guest users.\n");
0c330c1998-04-29Henrik Grubbström (Grubba)  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");
9b9f701997-08-12Per Hedbor  defvar("shells", "/etc/shells", "Shell database", TYPE_FILE|VAR_MORE,
cc18af1998-06-24Henrik Grubbström (Grubba)  "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");
14179b1997-01-29Per Hedbor  setvars(retrieve("spider#0", this)); }
b1fca01996-11-12Per Hedbor