eb6c692002-11-07Martin Nilsson // This is a ChiliMoon protocol module.
50c4c42001-08-23Martin Nilsson // Copyright © 2001, Roxen IS.
0d0e952000-11-13Per Hedbor inherit Protocol; constant supports_ipless = 0; constant name = "hilfe";
f4c6f92001-07-23Johan Sundström constant prot_name = "telnet";
3250252002-06-14Martin Nilsson constant requesthandlerfile = "plugins/protocols/hilfe.pike";
0d0e952000-11-13Per Hedbor constant default_port = 2345; class Connection { inherit Protocols.TELNET; Protocol my_port_obj; Configuration my_conf; Readline rl; Stdio.File fd; Handler handler; AdminUser user; class myRequestID { inherit RequestID;
3b57c82001-02-01Per Hedbor  string real_auth; string remoteaddr = "127.0.0.1";
86903b2003-01-23Martin Nilsson  static string _sprintf(int t) { return t=='O' && sprintf("%O(conf=%O; not_query=%O)", this_program, conf, not_query );
0d0e952000-11-13Per Hedbor  } static void create() { port_obj = my_port_obj; conf = my_conf; client = ({ "telnet" }); prot = "HILFE"; method = "GET";
3b57c82001-02-01Per Hedbor  real_variables = ([]);
99cb5e2001-02-05Per Hedbor  variables = FakedVariables( real_variables );
0d0e952000-11-13Per Hedbor  misc = ([]); cookies = ([]); throttle = ([]); client_var = ([]); request_headers = ([]); prestate = (<>); config = (<>); supports = (<>); pragma = (<>); rest_query = ""; extra_extension = ""; not_query = raw_url = "/"; } object last_module; string fix_msg( string msg, object|void mod ) { if( functionp( mod ) ) mod = function_object( mod ); if( mod ) last_module = mod; if(msg[-1] != '\n' ) msg += "\n"; string m = sprintf("%O:", last_module ); m = (m[..40]+" "[..39-strlen(m)]); return sprintf("%s%s", m, Roxen.html_decode_string(msg) ); } void debug_trace_enter_1( string msg, object module ) { rl->readline->write( fix_msg(indent+msg,module), 1 ); indent += " "; } void debug_trace_leave_1( string msg ) { indent = indent[..strlen(indent)-3]; } string indent=""; array old_backtrace; void debug_trace_enter_2( string msg, object module ) { array q = backtrace() - (old_backtrace||({})); rl->readline->write("\n\n"+describe_backtrace( q ) ); rl->readline->write( fix_msg(indent+msg,module), 1 ); indent += " "; } void debug_trace_leave_2( string msg, object module ) { old_backtrace = backtrace(); if( strlen( String.trim_all_whites(msg) ) ) rl->readline->write( fix_msg(indent+msg,0), 1 ); indent = indent[..strlen(indent)-3]; } this_program set_debug( int level ) { indent = ""; switch( level ) { case 0: misc->trace_enter = 0; misc->trace_leave = 0; break; case 1: misc->trace_enter = debug_trace_enter_1; misc->trace_leave = debug_trace_leave_1; break; default: misc->trace_enter = debug_trace_enter_2; misc->trace_leave = debug_trace_leave_2; break; } return this_object(); } this_program set_path( string f ) { raw_url = Roxen.http_encode_string( f ); if( strlen( f ) > 5 ) { string a; switch( f[1] ) { case '<': if (sscanf(f, "/<%s>/%s", a, f)==2) { config = (multiset)(a/","); f = "/"+f; } // intentional fall-through case '(': if(strlen(f) && sscanf(f, "/(%s)/%s", a, f)==2) { prestate = (multiset)( a/","-({""}) ); f = "/"+f; } } } not_query = Roxen.simplify_path( scan_for_query( f ) ); return this_object(); } this_program set_url( string url ) { Configuration c;
86903b2003-01-23Martin Nilsson  foreach(core->urls; string u; mixed q )
0d0e952000-11-13Per Hedbor  { if( glob( u+"*", url ) )
86903b2003-01-23Martin Nilsson  if( (c=q->port->find_configuration_for_url(url, this_object(), 1)) )
0d0e952000-11-13Per Hedbor  { conf = c; break; } } if(!c) { // pass 2: Find a configuration with the 'default' flag set.
86903b2003-01-23Martin Nilsson  foreach( core->configurations, c )
0d0e952000-11-13Per Hedbor  if( c->query( "default_server" ) ) { conf = c; break; } else c = 0; } if(!c) { // pass 3: No such luck. Let's allow default fallbacks.
86903b2003-01-23Martin Nilsson  foreach( core->urls; string u; mixed q )
0d0e952000-11-13Per Hedbor  {
86903b2003-01-23Martin Nilsson  if( (c=q->port->find_configuration_for_url(url, this_object(), 1)) )
0d0e952000-11-13Per Hedbor  { conf = c; break; } } } string host; sscanf( url, "%s://%s/%s", prot, host, url ); misc->host = host; return set_path( "/"+url ); } } class InsinuateFirst { mixed query( string what ) { return 0; } void first_try( RequestID id ) { if(catch { rl->readline->write( sprintf("Request for %s in %O from %s\n", id->not_query, id->conf, id->remoteaddr),1); }) { id->conf->pri[4]->first_modules -= ({ this_object() }); id->conf->invalidate_cache(); } } }
eb6c692002-11-07Martin Nilsson  class CommandDebug { inherit Tools.Hilfe.Command; string help(string what) { return "Debug ChiliMoon"; } void exec(Tools.Hilfe.Evaluator e, string line, array(string) words, array(string) tokens) { if(sizeof(words)!=2) { e->safe_write(help("")+"\n"); return; } switch( words[1] ) {
0d0e952000-11-13Per Hedbor  case "accesses":
86903b2003-01-23Martin Nilsson  foreach( core->configurations, Configuration c )
eb6c692002-11-07Martin Nilsson  if( c->inited ) {
0d0e952000-11-13Per Hedbor  c->pri[4]->first_modules += ({ InsinuateFirst() }); c->invalidate_cache(); }
eb6c692002-11-07Martin Nilsson  e->safe_write("Access debug started\n");
0d0e952000-11-13Per Hedbor  break; default:
eb6c692002-11-07Martin Nilsson  e->safe_write(help("")+"\n"); } } } class CommandExit { inherit Tools.Hilfe.Command; string help(string what) { return "Exit Hilfe."; } void exec(Tools.Hilfe.Evaluator e, string line, array(string) words, array(string) tokens) { begone();
0d0e952000-11-13Per Hedbor  } }
0dc2792002-03-19Martin Nilsson  class Handler { inherit Tools.Hilfe.Evaluator; void got_data( string d ) {
eb6c692002-11-07Martin Nilsson  replace(d, "\r", "\n"); sscanf(d, "%s\n", d);
0dc2792002-03-19Martin Nilsson  add_input_line( d );
eb6c692002-11-07Martin Nilsson  if(catch(state)) return;
0dc2792002-03-19Martin Nilsson  write( state->finishedp() ? "> " : ">> " ); user->settings->set("hilfe_history", rl->readline->get_history()->encode()); user->settings->save(); } void create() { ::create(); write = lambda(string ... in) { rl->readline->write(sprintf(@in)); };
89d5362002-06-03Martin Nilsson  commands->exit = CommandExit(); commands->quit = commands->exit;
eb6c692002-11-07Martin Nilsson  commands->debug = CommandDebug();
0dc2792002-03-19Martin Nilsson  constants["RequestID"] = myRequestID; constants["conf"] = my_conf; constants["port"] = my_port_obj; constants["user"] = user; user->settings->defvar( "hilfe_history", Variable.String("", 65535,0,0 ) ); user->settings->restore( ); string hi; if( (hi = user->settings->query("hilfe_history")) != "" ) rl->readline->get_history()->create( 512, hi/"\n" ); rl->readline->get_history()->finishline(""); print_version(); got_data(""); } }
0d0e952000-11-13Per Hedbor  #define USER 0 #define PASSWORD 1 #define LEAVE 2 #define DATA 3 int state = USER; void got_user_line( mixed q, string line ) { switch( state ) { case USER:
86903b2003-01-23Martin Nilsson  if(!(user = core.find_admin_user( line-"\n" ) ) )
0d0e952000-11-13Per Hedbor  { rl->readline->write("No such user: '"+(line-"\n")+"'\n"); } else { state++; } break; case PASSWORD: if( !crypt(line-"\n", user->password) ) { rl->readline->write("Wrong password\n"); state=USER; } else { if( !my_port_obj->query( "require_auth" ) || user->auth( "Hilfe" ) ) state++; else { rl->readline->write("User lacks permission to access hilfe\n"); state = USER; } } break; default: handler->got_data( line ); return; } switch( state ) { case USER: rl->set_secret( 0 ); rl->readline->write("User: "); break; case PASSWORD: rl->set_secret( 1 ); rl->readline->write("Password: "); break; case LEAVE: rl->set_secret( 0 ); state++; handler = Handler( ); signal( signum("ALRM"), handle_alarm ); update_lu(); handle_alarm(); break; } } int last_update; void update_lu() { last_update = time(); call_out( update_lu, 1.0 ); } void handle_alarm( ) {
2548452001-08-27Martin Stjernholm #if constant (alarm) // Pike@NT doesn't have this. This "fix" ought to be better..
0d0e952000-11-13Per Hedbor  alarm( 1 );
2548452001-08-27Martin Stjernholm #endif
0d0e952000-11-13Per Hedbor  if( time()-last_update > 5 )
a51a902001-11-12Martin Stjernholm  error( "Too long evaluation\n" );
0d0e952000-11-13Per Hedbor  } void begone() {
0dc2792002-03-19Martin Nilsson  catch(fd->write("\nBye\n"));
0d0e952000-11-13Per Hedbor  catch(fd->close()); catch(destruct( fd )); catch(destruct( handler )); catch(destruct( this_object() )); } void write_more() { } int n; static void init2( ) { if( rl->readline ) {
eb6c692002-11-07Martin Nilsson  rl->readline->write("Welcome to ChiliMoon Hilfe 1.2\n", 1);
0d0e952000-11-13Per Hedbor  rl->readline->write("Username: "); return; } n++; if( n < 100 ) call_out( init2, 0.1 ); else { rl->message("Failed to set up terminal.\n"); begone(); } } static void create(object f, object c, object cc) { my_port_obj = c; my_conf = cc; fd = f; rl = Readline( f, got_user_line, 0, begone, 0 ); call_out( init2, 0.1 ); } } void create( mixed ... args ) {
86903b2003-01-23Martin Nilsson  core.add_permission( "Hilfe", "Hilfe" ); core.set_up_hilfe_variables( this_object() );
0d0e952000-11-13Per Hedbor  requesthandler = Connection; ::create( @args ); }