Roxen.git / server / base_server / roxen.pike

version» Context lines:

Roxen.git/server/base_server/roxen.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2004, Roxen IS.   //   // The Roxen WebServer main program.   //   // Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.   // ABS and suicide systems contributed freely by Francesco Chemolli    - constant cvs_version="$Id: roxen.pike,v 1.978 2008/07/01 19:44:20 grubba Exp $"; + constant cvs_version="$Id: roxen.pike,v 1.979 2008/08/05 22:15:44 mast Exp $";      //! @appears roxen   //!   //! The Roxen WebServer main program.      // The argument cache. Used by the image cache.   ArgCache argcache;      // Some headerfiles   #define IN_ROXEN
Roxen.git/server/base_server/roxen.pike:119: Inside #if defined(THREADS)
  string thread_name( object thread )   {    string tn;    if( thread_names[ tn=sprintf("%O",thread) ] )    return thread_names[tn];    return tn;   }      void name_thread( object thread, string name )   { -  catch(thread->set_name( name )); +     thread_names[ sprintf( "%O", thread ) ] = name;   }      // This mutex is used by Privs   Thread.Mutex euid_egid_lock = Thread.Mutex();   #endif /* THREADS */      /*    * The privilege changer. Works like a mutex lock, but changes the UID/GID    * while held. Blocks all threads.
Roxen.git/server/base_server/roxen.pike:187: Inside #if defined(PRIVS_DEBUG)
   report_debug(sprintf("Privs(%O, %O, %O)\n"    "privs_level: %O\n",    reason, uid, gid, privs_level));   #endif /* PRIVS_DEBUG */      #ifdef HAVE_EFFECTIVE_USER    array u;      #ifdef THREADS    if (euid_egid_lock) { -  catch { mutex_key = euid_egid_lock->lock(); }; +  if (mixed err = catch { mutex_key = euid_egid_lock->lock(); }) +  werror (describe_backtrace (err));    }    threads_disabled = _disable_threads();   #endif /* THREADS */       p_level = privs_level++;       /* Needs to be here since root-priviliges may be needed to    * use getpw{uid,nam}.    */    saved_uid = geteuid();
Roxen.git/server/base_server/roxen.pike:247: Inside #if defined(HAVE_EFFECTIVE_USER)
   }       if(LOGP)    report_notice(LOC_M(1, "Change to %s(%d):%d privs wanted (%s), from %s"),    (string)u[0], (int)uid, (int)gid,    (string)reason,    (string)dbt(backtrace()[-2]));       if (u[2]) {   #if efun(cleargroups) -  catch { cleargroups(); }; +  if (mixed err = catch { cleargroups(); }) +  werror (describe_backtrace (err));   #endif /* cleargroups */   #if efun(initgroups) -  catch { initgroups(u[0], u[3]); }; +  if (mixed err = catch { initgroups(u[0], u[3]); }) +  werror (describe_backtrace (err));   #endif    }    gid = gid || getgid();    int err = (int)setegid(new_gid = gid);    if (err < 0) {    report_warning(LOC_M(2, "Privs: WARNING: Failed to set the "    "effective group id to %d!\n"    "Check that your password database is correct "    "for user %s(%d),\n and that your group "    "database is correct.\n"),
Roxen.git/server/base_server/roxen.pike:333: Inside #if defined(HAVE_EFFECTIVE_USER)
   report_error(sprintf("Change back to uid#%d gid#%d from uid#%d gid#%d\n"    "Skips privs level. Saved level:%d Current level:%d\n"    "Occurs in:\n%s\n",    saved_uid, saved_gid, new_uid, new_gid,    p_level, privs_level,    describe_backtrace(backtrace())));    }    privs_level = p_level;       if(LOGP) { -  catch { +  if (mixed err = catch {    array bt = backtrace();    if (sizeof(bt) >= 2) {    report_notice(LOC_M(3,"Change back to uid#%d gid#%d, from %s")+"\n",    saved_uid, saved_gid, dbt(bt[-2]));    } else {    report_notice(LOC_M(4,"Change back to uid#%d gid#%d, "    "from backend")+"\n", saved_uid, saved_gid);    } -  }; +  }) +  werror (describe_backtrace (err));    }      #ifdef PRIVS_DEBUG    int uid = geteuid();    if (uid != new_uid) {    report_debug("Privs: UID #%d differs from expected #%d\n"    "%s\n",    uid, new_uid, describe_backtrace(backtrace()));    }    int gid = getegid();    if (gid != new_gid) {    report_debug("Privs: GID #%d differs from expected #%d\n"    "%s\n",    gid, new_gid, describe_backtrace(backtrace()));    }   #endif /* PRIVS_DEBUG */       seteuid(0);    array u = getpwuid(saved_uid);   #if efun(cleargroups) -  catch { cleargroups(); }; +  if (mixed err = catch { cleargroups(); }) +  werror (describe_backtrace (err));   #endif /* cleargroups */    if(u && (sizeof(u) > 3)) { -  catch { initgroups(u[0], u[3]); }; +  if (mixed err = catch { initgroups(u[0], u[3]); }) +  werror (describe_backtrace (err));    }    setegid(saved_gid);    seteuid(saved_uid);    enable_coredumps(1);   #endif /* HAVE_EFFECTIVE_USER */    }   #else /* efun(seteuid) */    void create(string reason, int|string|void uid, int|string|void gid){}   #endif /* efun(seteuid) */   }
Roxen.git/server/base_server/roxen.pike:433:    release_handler_threads(3);   #endif    configurations->stop(1);   }      // Function that actually shuts down Roxen. (see low_shutdown).   private void really_low_shutdown(int exit_code)   {    // Die nicely. Catch for paranoia reasons   #ifdef THREADS -  catch (stop_handler_threads()); +  if (mixed err = catch (stop_handler_threads())) +  werror (describe_backtrace (err));   #endif /* THREADS */    if (!exit_code || once_mode) {    // We're shutting down; Attempt to take mysqld with us. -  catch { report_notice("Shutting down MySQL.\n"); }; +  if (mixed err = +  catch { report_notice("Shutting down MySQL.\n"); } ||    catch { -  Sql.sql db = connect_to_my_mysql(0, "mysql"); +  Sql.Sql db = connect_to_my_mysql(0, "mysql");    db->shutdown(); -  }; +  }) +  werror (describe_backtrace (err));    }    destruct (cache);   #if 0    // Disabled since it's lying when the server is shut down with a    // SIGTERM or SIGINT to the start script (which include the stop    // action of the init.d script). -  catch { +  if (mixed err = catch {    if (exit_code && !once_mode)    report_notice("Restarting Roxen.\n");    else    report_notice("Shutting down Roxen.\n"); -  }; +  }) +  werror (describe_backtrace (err));   #endif    roxenloader.real_exit( exit_code ); // Now we die...   }      private int _recurse;      // Shutdown Roxen   // exit_code = 0 True shutdown   // exit_code = -1 Restart   private void low_shutdown(int exit_code)   {    if(_recurse >= 4)    { -  catch (report_notice("Exiting roxen (spurious signals received).\n")); -  catch (stop_all_configurations()); +  if (mixed err = +  catch (report_notice("Exiting roxen (spurious signals received).\n")) || +  catch (stop_all_configurations())) +  werror (describe_backtrace (err));    destruct(cache);   #ifdef THREADS -  catch (stop_handler_threads()); +  if (mixed err = catch (stop_handler_threads())) +  werror (describe_backtrace (err));   #endif /* THREADS */    roxenloader.real_exit(exit_code);    }    if (_recurse++) return;    -  catch(stop_all_configurations()); +  if (mixed err = catch(stop_all_configurations())) +  werror (describe_backtrace (err));      #ifdef SNMP_AGENT    if(objectp(snmpagent)) {    snmpagent->stop_trap();    snmpagent->disable();    }   #endif       call_out(really_low_shutdown, 0.1, exit_code);   }
Roxen.git/server/base_server/roxen.pike:2779: Inside #if undefined(__NT__)
   }    report_debug("**** %s: ABS engaged!\n"    "Waited more than %d minute(s).\n",    ctime(time()) - "\n",    query("abs_timeout"));    // Paranoia exit in case describe_all_threads below hangs.    signal(signum("SIGALRM"), low_engage_abs);    int t = alarm(20);   #ifdef THREADS    report_debug("Handler queue:\n"); -  catch { +  if (mixed err = catch {    array(mixed) queue = handle_queue->buffer[handle_queue->r_ptr..];    foreach(queue, mixed v) {    if (!v) continue;    if (!arrayp(v)) {    report_debug(" *** Strange entry: %O ***\n", v);    } else {    report_debug(" %{%O, %}\n", v/({}));    }    } -  }; +  }) +  werror (describe_backtrace (err));   #endif    report_debug("Trying to dump backlog: \n"); -  catch { +  if (mixed err = catch {    // Catch for paranoia reasons.    describe_all_threads(); -  }; +  }) +  werror (describe_backtrace (err));    low_engage_abs();   }      void restart_if_stuck (int force)   //! @note   //! Must be called from the backend thread due to Linux peculiarities.   {    remove_call_out(restart_if_stuck);    if (!(query("abs_engage") || force))    return;
Roxen.git/server/base_server/roxen.pike:3601:    werror("restore %O\n", id );   #endif    q = QUERY( "SELECT meta,atime,data FROM "+name+" WHERE id=%s",id);    if( sizeof(q) )    {    if( sizeof(q[0]->data) )    {    // Case 1: We have cache entry and image.    string f = q[0]->data;    mapping m; -  catch( m = decode_value( q[0]->meta ) ); +  if (mixed err = catch( m = decode_value( q[0]->meta ) )) +  report_debug ("Failed to decode meta mapping for id %O in %s: %s", +  id, name, describe_error (err));    if( !m ) return 0;       m = Roxen.http_string_answer( f, m->type||("image/gif") );       if( strlen( f ) > 6000 )    return m;    rst_cache[ id ] = m;    if( sizeof( rst_cache ) > 100 )    rst_cache = ([ id : m ]);    return rst_cache[ id ] + ([]);
Roxen.git/server/base_server/roxen.pike:3914:   {   #undef QUERY   #define QUERY(X,Y...) db->query(X,Y)    Sql.Sql db;    string name;      #define CACHE_SIZE 900       Thread.Mutex mutex = Thread.Mutex();    // Allow recursive locks, since it's normal here. - # define LOCK() mixed __; catch( __ = mutex->lock() ) + # define LOCK() mixed __ = mutex->lock (2)      #ifdef ARGCACHE_DEBUG   #define dwerror(ARGS...) werror(ARGS)   #else   #define dwerror(ARGS...) 0   #endif       static mapping(string|int:mixed) cache = ([ ]);       static void setup_table()
Roxen.git/server/base_server/roxen.pike:4192:    if(!secret || !has_prefix(secret, SECRET_TAG))    // New pakage found, restore input stream.    file->ungets(secret);       string s;    while(s = file->gets())    {    if(s == "EOF")    return 0;    array a; -  if(catch { +  if(mixed err = catch {    a = decode_value(MIME.decode_base64(s)); -  }) return "Decode failed for argcache record\n"; +  }) return "Decode failed for argcache record: " + describe_error (err);       if(sizeof(a) == 4) {    // Old style argcache dump.    dwerror("ArgCache.read_dump(): value_id: %O, index_id: %O.\n", a[0], a[2]);    if (a[2] == -1)    // The old write_dump didn't filter out entries with NULL    // index_id when from_time was zero, so we ignore them here    // instead.    dwerror ("ArgCache.read_dump(): entry ignored.\n");    else {
Roxen.git/server/base_server/roxen.pike:4443:    u = pw[0], uid = pw[2];    if (!g) gid = pw[3];    }      #ifdef THREADS    Thread.MutexKey mutex_key;    object threads_disabled;    if (!from_handler_thread) {    // If this is necessary from every handler thread, these    // things are thread local and thus are no locks necessary. -  catch { mutex_key = euid_egid_lock->lock(); }; +  if (mixed err = catch { mutex_key = euid_egid_lock->lock(); }) +  werror (describe_backtrace (err));    threads_disabled = _disable_threads();    }   #endif      #if constant(seteuid)    if (geteuid() != getuid()) seteuid (getuid());   #endif      #if constant(initgroups) -  catch { +  if (mixed err = catch {    initgroups(pw[0], gid);    // Doesn't always work - David. -  }; +  }) +  werror (describe_backtrace (err));   #endif       if (query("permanent_uid")) {   #if constant(setuid)    if (g) {   # if constant(setgid)    setgid(gid);    if (getgid() != gid) {    report_error(LOC_M(25, "Failed to set gid.")+"\n");    g = 0;
Roxen.git/server/base_server/roxen.pike:4720:    // We were recursing very badly with the demo module here...    id->misc->_load_image_called++;    if(!(data=id->conf->try_get_file(f, id, 0, 0, 0, err)))    {    // This is a major security hole! It can load any (image) file    // in the low-level file system using the server's user privileges.    //    // file=Stdio.File();    // if(!file->open(f,"r") || !(data=file->read()))   #ifdef THREADS -  catch +  if (mixed err = catch    {    string host = "";    sscanf( f, "http://%[^/]", host );    if( sscanf( host, "%*s:%*d" ) != 2)    host += ":80";    mapping hd =    ([    "User-Agent":version(),    "Host":host,    ]);    data = Protocols.HTTP.get_url_data( f, 0, hd ); -  }; +  }) +  werror (describe_backtrace (err));   #endif    if( !data )    return 0;    }    }    id->misc->_load_image_called = 0;    if(!data) return 0;    return low_decode_image( data );   }   
Roxen.git/server/base_server/roxen.pike:4759:    // We were recursing very badly with the demo module here...    id->misc->_load_image_called++;    if(!(data=id->conf->try_get_file(f, id, 0, 0, 0, res)))    {    // This is a major security hole! It can load any (image) file    // in the low-level file system using the server's user privileges.    //    // file=Stdio.File();    // if(!file->open(f,"r") || !(data=file->read()))   // #ifdef THREADS -  catch +  if (mixed err = catch    {    data = Protocols.HTTP.get_url_nice( f )[1]; -  }; +  }) +  werror (describe_backtrace (err));   // #endif    if( !data )    return res;    }    }    id->misc->_load_image_called = 0;    if(!data) return res;    return decode_layers( data, opt );   }   
Roxen.git/server/base_server/roxen.pike:4815:   void create_pid_file(string where)   {   #ifndef __NT__    if(!where) return;   // where = replace(where, ({ "$pid", "$uid" }),   // ({ (string)getpid(), (string)getuid() }));       object privs = Privs("Deleting old pid file.");    r_rm(where);    privs = 0; -  if(catch(Stdio.write_file(where, sprintf("%d\n%d\n", getpid(), getppid())))) -  report_debug("I cannot create the pid file ("+where+").\n"); +  if(mixed err = catch { +  Stdio.write_file(where, sprintf("%d\n%d\n", getpid(), getppid())); +  }) +  report_debug("Cannot create the pid file %O: %s", +  where, describe_error (err));   #endif   }      Pipe.pipe shuffle(Stdio.File from, Stdio.File to,    Stdio.File|void to2,    function(:void)|void callback)   {   #if efun(spider.shuffle)    if(!to2)    {