835c6c | 2001-06-17 | Martin Nilsson | |
|
b655bf | 2004-06-30 | Martin Stjernholm | |
|
835c6c | 2001-06-17 | Martin Nilsson | |
|
24c6c1 | 2000-02-20 | Martin Nilsson | |
|
02ee41 | 2000-12-17 | Henrik Grubbström (Grubba) | |
|
edc9af | 1998-07-11 | David Hedbor | |
|
835c6c | 2001-06-17 | Martin Nilsson | |
|
c86a47 | 2005-11-14 | Martin Stjernholm | | constant cvs_version="$Id: roxen.pike,v 1.907 2005/11/14 13:00:47 mast Exp $";
|
5d3e44 | 2002-12-09 | Henrik Grubbström (Grubba) | |
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
855c39 | 1999-11-29 | Per Hedbor | | ArgCache argcache;
|
172054 | 1998-10-04 | Henrik Grubbström (Grubba) | |
|
4dd97c | 1996-12-04 | Per Hedbor | | #define IN_ROXEN
|
8540e1 | 1997-06-14 | Francesco Chemolli | | #include <roxen.h>
#include <config.h>
|
b1fca0 | 1996-11-12 | Per Hedbor | | #include <module.h>
#include <variables.h>
|
753a83 | 1999-08-30 | Per Hedbor | | #include <stat.h>
|
9c1900 | 2001-02-27 | Per Hedbor | | #include <timers.h>
|
14179b | 1997-01-29 | Per Hedbor | |
|
172054 | 1998-10-04 | Henrik Grubbström (Grubba) | |
|
753a83 | 1999-08-30 | Per Hedbor | | inherit "global_variables";
|
6897c9 | 2001-06-27 | Honza Petrous | | #ifdef SNMP_AGENT
inherit "snmpagent";
#endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | inherit "hosts";
inherit "disk_cache";
|
970e24 | 2000-09-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | inherit "supports";
|
08eba6 | 2000-07-09 | Per Hedbor | | inherit "module_support";
|
970e24 | 2000-09-12 | Per Hedbor | | inherit "config_userdb";
|
7c92b9 | 1998-11-19 | Per Hedbor | |
|
79c3a6 | 2001-04-25 | Jonas Wallden | | #ifdef THREADS
Thread.Thread backend_thread;
#endif /* THREADS */
|
23414a | 2000-07-21 | Andreas Lange | |
#define LOC_S(X,Y) _STR_LOCALE("roxen_start",X,Y)
#define LOC_M(X,Y) _STR_LOCALE("roxen_message",X,Y)
#define CALL_M(X,Y) _LOCALE_FUN("roxen_message",X,Y)
|
be788e | 2000-03-27 | Martin Nilsson | |
|
81f8af | 1999-12-20 | Martin Nilsson | |
#ifdef SSL3_DEBUG
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | # define SSL3_WERR(X) report_debug("TLS port %s: %s\n", get_url(), X)
|
81f8af | 1999-12-20 | Martin Nilsson | | #else
|
bfb4d4 | 1999-12-28 | Martin Nilsson | | # define SSL3_WERR(X)
|
81f8af | 1999-12-20 | Martin Nilsson | | #endif
#ifdef THREAD_DEBUG
|
3e6f6b | 2001-03-11 | Martin Nilsson | | # define THREAD_WERR(X) report_debug("Thread: "+X+"\n")
|
81f8af | 1999-12-20 | Martin Nilsson | | #else
|
bfb4d4 | 1999-12-28 | Martin Nilsson | | # define THREAD_WERR(X)
|
81f8af | 1999-12-20 | Martin Nilsson | | #endif
|
60a912 | 1999-10-10 | Henrik Grubbström (Grubba) | |
|
8cc5fc | 2003-03-05 | Martin Stjernholm | |
#if constant(System.dumpable)
#define enable_coredumps(X) System.dumpable(X)
#elif constant(system.dumpable)
#define enable_coredumps(X) system.dumpable(X)
#else
#define enable_coredumps(X)
#endif
|
851483 | 2000-11-27 | Per Hedbor | | #define DDUMP(X) sol( combine_path( __FILE__, "../../" + X ), dump )
static function sol = master()->set_on_load;
|
aa7872 | 2001-08-24 | Martin Stjernholm | | #ifdef TEST_EUID_CHANGE
int test_euid_change;
#endif
|
50b697 | 2001-08-31 | Per Hedbor | | string md5( string what )
{
return Gmp.mpz(Crypto.md5()->update( what )->digest(),256)
->digits(32);
}
|
970e24 | 2000-09-12 | Per Hedbor | | string query_configuration_dir()
{
return configuration_dir;
}
|
855c39 | 1999-11-29 | Per Hedbor | |
|
596425 | 1999-11-19 | Per Hedbor | | string filename( program|object o )
|
95b69e | 1999-09-05 | Per Hedbor | | {
|
596425 | 1999-11-19 | Per Hedbor | | if( objectp( o ) )
o = object_program( o );
|
2537c3 | 2000-02-14 | Per Hedbor | | string fname = master()->program_name( o );
|
596425 | 1999-11-19 | Per Hedbor | | if( !fname )
fname = "Unknown Program";
return fname-(getcwd()+"/");
|
95b69e | 1999-09-05 | Per Hedbor | | }
|
b21503 | 2004-05-04 | Henrik Grubbström (Grubba) | | static int once_mode;
|
8cbc5f | 2002-09-03 | Martin Stjernholm | |
|
0dabc6 | 2004-08-27 | Anders Johansson | | array(string) compat_levels = ({"2.1", "2.2", "2.4", "2.5", "3.3", "3.4", "4.0", "4.1" });
|
b0a9ea | 2001-04-18 | Martin Stjernholm | |
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #ifdef THREADS
|
666412 | 2001-02-23 | Per Hedbor | | mapping(string:string) thread_names = ([]);
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;
}
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
855c39 | 1999-11-29 | Per Hedbor | | Thread.Mutex euid_egid_lock = Thread.Mutex();
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* THREADS */
|
c5e096 | 1999-10-04 | Per Hedbor | | |
8fb517 | 2000-05-27 | Per Hedbor | | * The privilege changer. Works like a mutex lock, but changes the UID/GID
* while held. Blocks all threads.
*
|
c5e096 | 1999-10-04 | Per Hedbor | | * Based on privs.pike,v 1.36.
*/
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | int privs_level;
|
81f8af | 1999-12-20 | Martin Nilsson | | static class Privs
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #if efun(seteuid)
int saved_uid;
int saved_gid;
int new_uid;
int new_gid;
|
7b798d | 2000-07-04 | Per Hedbor | | #define LOGP (variables && variables->audit && variables->audit->query())
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
#if constant(geteuid) && constant(getegid) && constant(seteuid) && constant(setegid)
#define HAVE_EFFECTIVE_USER
#endif
static private string _getcwd()
{
if (catch{return(getcwd());}) {
return("Unknown directory (no x-bit on current directory?)");
}
}
static private string dbt(array t)
{
if(!arrayp(t) || (sizeof(t)<2)) return "";
return (((t[0]||"Unknown program")-(_getcwd()+"/"))-"base_server/")+":"+t[1]+"\n";
}
#ifdef THREADS
|
b84a16 | 1999-06-07 | Martin Stjernholm | | static mixed mutex_key;
|
d3a71c | 1999-04-20 | Martin Stjernholm | | static object threads_disabled;
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* THREADS */
int p_level;
void create(string reason, int|string|void uid, int|string|void gid)
{
|
f19828 | 2001-09-27 | Henrik Grubbström (Grubba) | |
if(getuid()) return;
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #ifdef PRIVS_DEBUG
|
3e6f6b | 2001-03-11 | Martin Nilsson | | report_debug(sprintf("Privs(%O, %O, %O)\n"
"privs_level: %O\n",
reason, uid, gid, privs_level));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* PRIVS_DEBUG */
#ifdef HAVE_EFFECTIVE_USER
array u;
#ifdef THREADS
if (euid_egid_lock) {
catch { mutex_key = euid_egid_lock->lock(); };
}
|
d3a71c | 1999-04-20 | Martin Stjernholm | | threads_disabled = _disable_threads();
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* THREADS */
p_level = privs_level++;
saved_uid = geteuid();
saved_gid = getegid();
seteuid(0);
|
c5e096 | 1999-10-04 | Per Hedbor | | if(stringp(uid) && (replace(uid,"0123456789"/"",({""})*10)==""))
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | uid = (int)uid;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
3a4b9a | 1999-12-27 | Martin Nilsson | | if(stringp(gid) && (replace(gid, "0123456789"/"", ({"" })*10) == ""))
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | gid = (int)gid;
|
c5e096 | 1999-10-04 | Per Hedbor | | if(!stringp(uid))
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | u = getpwuid(uid);
|
81f8af | 1999-12-20 | Martin Nilsson | | else
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | u = getpwnam(uid);
|
81f8af | 1999-12-20 | Martin Nilsson | | if(u)
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | uid = u[2];
}
|
eae43a | 2001-08-13 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | if(u && !gid)
|
c5e096 | 1999-10-04 | Per Hedbor | | gid = u[3];
|
81f8af | 1999-12-20 | Martin Nilsson | |
if(!u)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
81f8af | 1999-12-20 | Martin Nilsson | | if (uid && (uid != "root"))
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
81f8af | 1999-12-20 | Martin Nilsson | | if (intp(uid) && (uid >= 60000))
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
b84a16 | 1999-06-07 | Martin Stjernholm | | report_warning(sprintf("Privs: User %d is not in the password database.\n"
"Assuming nobody.\n", uid));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
gid = gid || uid;
u = ({ "fake-nobody", "x", uid, gid, "A real nobody", "/", "/sbin/sh" });
} else {
error("Unknown user: "+uid+"\n");
}
} else {
u = ({ "root", "x", 0, gid, "The super-user", "/", "/sbin/sh" });
}
}
if(LOGP)
|
49cd28 | 2000-08-11 | Andreas Lange | | report_notice(LOC_M(1, "Change to %s(%d):%d privs wanted (%s), from %s"),
|
23414a | 2000-07-21 | Andreas Lange | | (string)u[0], (int)uid, (int)gid,
(string)reason,
(string)dbt(backtrace()[-2]));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
996384 | 2001-09-26 | Martin Stjernholm | | if (u[2]) {
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #if efun(cleargroups)
|
996384 | 2001-09-26 | Martin Stjernholm | | catch { cleargroups(); };
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* cleargroups */
#if efun(initgroups)
|
996384 | 2001-09-26 | Martin Stjernholm | | catch { initgroups(u[0], u[3]); };
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif
|
996384 | 2001-09-26 | Martin Stjernholm | | }
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | gid = gid || getgid();
int err = (int)setegid(new_gid = gid);
if (err < 0) {
|
49cd28 | 2000-08-11 | Andreas Lange | | report_warning(LOC_M(2, "Privs: WARNING: Failed to set the "
|
23414a | 2000-07-21 | Andreas Lange | | "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"),
gid, (string)u[0], (int)uid);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | int gid2 = gid;
#ifdef HPUX_KLUDGE
if (gid >= 60000) {
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Privs: WARNING: Assuming nobody-group.\n"
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | "Trying some alternatives...\n");
foreach(({ 60001, 65534, -2 }), gid2) {
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("%d... ", gid2);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | if (initgroups(u[0], gid2) >= 0) {
if ((err = setegid(new_gid = gid2)) >= 0) {
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Success!\n");
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | break;
}
}
}
}
#endif /* HPUX_KLUDGE */
if (err < 0) {
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Privs: Failed\n");
|
3b76dc | 2002-01-29 | Martin Stjernholm | | error ("Failed to set EGID to %d\n", gid);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Privs: WARNING: Set egid to %d instead of %d.\n",
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | gid2, gid);
gid = gid2;
}
if(getgid()!=gid) setgid(gid||getgid());
seteuid(new_uid = uid);
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | enable_coredumps(1);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* HAVE_EFFECTIVE_USER */
}
void destroy()
{
|
f19828 | 2001-09-27 | Henrik Grubbström (Grubba) | |
if(getuid()) return;
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #ifdef PRIVS_DEBUG
|
3e6f6b | 2001-03-11 | Martin Nilsson | | report_debug(sprintf("Privs->destroy()\n"
"privs_level: %O\n",
privs_level));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* PRIVS_DEBUG */
#ifdef HAVE_EFFECTIVE_USER
if (p_level >= privs_level) {
report_error(sprintf("Change back to uid#%d gid#%d from uid#%d gid#%d\n"
"in wrong order! 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())));
return(0);
}
if (p_level != privs_level-1) {
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 {
array bt = backtrace();
if (sizeof(bt) >= 2) {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_notice(LOC_M(3,"Change back to uid#%d gid#%d, from %s")+"\n",
|
23414a | 2000-07-21 | Andreas Lange | | saved_uid, saved_gid, dbt(bt[-2]));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | } else {
|
49cd28 | 2000-08-11 | Andreas Lange | | report_notice(LOC_M(4,"Change back to uid#%d gid#%d, "
|
c8ee71 | 2000-09-09 | Andreas Lange | | "from backend")+"\n", saved_uid, saved_gid);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
};
}
|
81f8af | 1999-12-20 | Martin Nilsson | | #ifdef PRIVS_DEBUG
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | int uid = geteuid();
if (uid != new_uid) {
|
3e6f6b | 2001-03-11 | Martin Nilsson | | report_debug("Privs: UID #%d differs from expected #%d\n"
"%s\n",
uid, new_uid, describe_backtrace(backtrace()));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
int gid = getegid();
if (gid != new_gid) {
|
3e6f6b | 2001-03-11 | Martin Nilsson | | report_debug("Privs: GID #%d differs from expected #%d\n"
"%s\n",
gid, new_gid, describe_backtrace(backtrace()));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
81f8af | 1999-12-20 | Martin Nilsson | | #endif /* PRIVS_DEBUG */
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
seteuid(0);
array u = getpwuid(saved_uid);
#if efun(cleargroups)
catch { cleargroups(); };
#endif /* cleargroups */
if(u && (sizeof(u) > 3)) {
catch { initgroups(u[0], u[3]); };
}
setegid(saved_gid);
seteuid(saved_uid);
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | enable_coredumps(1);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* HAVE_EFFECTIVE_USER */
}
|
dbfe9d | 2000-04-13 | Per Hedbor | | #else /* efun(seteuid) */
void create(string reason, int|string|void uid, int|string|void gid){}
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* efun(seteuid) */
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
3e3bab | 2001-01-19 | Per Hedbor | | static Privs PRIVS(string r, int|string|void u, int|string|void g)
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | {
return Privs(r, u, g);
}
|
333b54 | 2005-02-25 | Henrik Grubbström (Grubba) | |
Thread.Local current_configuration = Thread.Local();
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
3e3bab | 2001-01-19 | Per Hedbor | | class Fonts
{
class Font
{
Image.Image write( string ... what );
array(int) text_extents( string ... what );
};
array available_font_versions(string name, int size);
string describe_font_type(string n);
Font get_font(string f, int size, int bold, int italic,
string justification, float|int xspace, float|int yspace);
Font resolve_font(string f, string|void justification);
|
8a1290 | 2001-11-14 | Henrik Grubbström (Grubba) | | array(string) available_fonts(int(0..1)|void force_reload);
|
3e3bab | 2001-01-19 | Per Hedbor | | }
Fonts fonts;
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
d09399 | 2000-09-25 | Per Hedbor | |
|
9a8a15 | 2000-09-25 | Per Hedbor | | program _configuration;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
d09399 | 2000-09-25 | Per Hedbor | | array(Configuration) configurations = ({});
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
9567c1 | 2001-02-23 | Martin Stjernholm | | private void stop_all_configurations()
{
configurations->unregister_urls();
#ifdef THREADS
hold_handler_threads();
release_handler_threads(3);
#endif
configurations->stop(1);
}
|
172054 | 1998-10-04 | Henrik Grubbström (Grubba) | |
|
1e5cc4 | 2001-03-17 | Martin Stjernholm | | private void really_low_shutdown(int exit_code)
|
a9d811 | 1998-09-01 | Henrik Grubbström (Grubba) | | {
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
310710 | 1998-09-01 | Marcus Comstedt | | #ifdef THREADS
|
532b90 | 2001-08-13 | Martin Stjernholm | | catch (stop_handler_threads());
|
310710 | 1998-09-01 | Marcus Comstedt | | #endif /* THREADS */
|
b21503 | 2004-05-04 | Henrik Grubbström (Grubba) | | if (!exit_code || once_mode) {
|
c7ca24 | 2004-03-09 | Henrik Grubbström (Grubba) | |
catch { report_notice("Shutting down MySQL.\n"); };
catch {
Sql.sql db = connect_to_my_mysql(0, "mysql");
db->shutdown();
};
}
|
532b90 | 2001-08-13 | Martin Stjernholm | | destruct (cache);
|
8de870 | 2004-08-23 | Martin Stjernholm | | #if 0
|
532b90 | 2001-08-13 | Martin Stjernholm | | catch {
|
b21503 | 2004-05-04 | Henrik Grubbström (Grubba) | | if (exit_code && !once_mode)
|
1e5cc4 | 2001-03-17 | Martin Stjernholm | | report_notice("Restarting Roxen.\n");
else
report_notice("Shutting down Roxen.\n");
};
|
8de870 | 2004-08-23 | Martin Stjernholm | | #endif
|
4eeda6 | 2003-09-15 | Martin Stjernholm | | roxenloader.real_exit( exit_code );
|
a9d811 | 1998-09-01 | Henrik Grubbström (Grubba) | | }
|
1e5cc4 | 2001-03-17 | Martin Stjernholm | | private int _recurse;
|
e83c43 | 2001-03-11 | Martin Nilsson | |
|
a9d811 | 1998-09-01 | Henrik Grubbström (Grubba) | |
|
1e5cc4 | 2001-03-17 | Martin Stjernholm | | private void low_shutdown(int exit_code)
|
a9d811 | 1998-09-01 | Henrik Grubbström (Grubba) | | {
|
532b90 | 2001-08-13 | Martin Stjernholm | | if(_recurse >= 4)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
532b90 | 2001-08-13 | Martin Stjernholm | | catch (report_notice("Exiting roxen (spurious signals received).\n"));
catch (stop_all_configurations());
destruct(cache);
|
e83c43 | 2001-03-11 | Martin Nilsson | | #ifdef THREADS
|
532b90 | 2001-08-13 | Martin Stjernholm | | catch (stop_handler_threads());
|
e83c43 | 2001-03-11 | Martin Nilsson | | #endif /* THREADS */
|
4eeda6 | 2003-09-15 | Martin Stjernholm | | roxenloader.real_exit(exit_code);
|
e83c43 | 2001-03-11 | Martin Nilsson | | }
|
ee8bc3 | 2001-08-21 | Martin Stjernholm | | if (_recurse++) return;
|
e83c43 | 2001-03-11 | Martin Nilsson | |
|
79b7c3 | 2001-09-13 | Honza Petrous | | catch(stop_all_configurations());
|
6897c9 | 2001-06-27 | Honza Petrous | | #ifdef SNMP_AGENT
|
79b7c3 | 2001-09-13 | Honza Petrous | | if(objectp(snmpagent)) {
snmpagent->stop_trap();
|
6897c9 | 2001-06-27 | Honza Petrous | | snmpagent->disable();
|
79b7c3 | 2001-09-13 | Honza Petrous | | }
|
6897c9 | 2001-06-27 | Honza Petrous | | #endif
|
8fb517 | 2000-05-27 | Per Hedbor | | call_out(really_low_shutdown, 0.1, exit_code);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
a9d811 | 1998-09-01 | Henrik Grubbström (Grubba) | |
|
c974c9 | 1999-06-27 | Per Hedbor | |
|
7de3f3 | 2001-02-02 | Fredrik Noring | | void restart(float|void i, void|int exit_code)
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | {
|
7de3f3 | 2001-02-02 | Fredrik Noring | | call_out(low_shutdown, i, exit_code || -1);
|
81f8af | 1999-12-20 | Martin Nilsson | | }
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | void shutdown(float|void i)
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | {
call_out(low_shutdown, i, 0);
|
f4e1b7 | 1999-10-08 | Per Hedbor | | }
|
14179b | 1997-01-29 | Per Hedbor | |
|
e83c43 | 2001-03-11 | Martin Nilsson | | void exit_when_done()
{
report_notice("Interrupt request received.\n");
low_shutdown(-1);
}
|
4820e0 | 1999-07-27 | Henrik Grubbström (Grubba) | |
|
34fbbc | 1998-02-05 | Henrik Grubbström (Grubba) | | #ifdef THREADS
|
50b58b | 2001-01-31 | Per Hedbor | |
|
34fbbc | 1998-02-05 | Henrik Grubbström (Grubba) | |
|
3e3bab | 2001-01-19 | Per Hedbor | | Thread do_thread_create(string id, function f, mixed ... args)
|
4f4bc1 | 1998-02-04 | Per Hedbor | | {
|
3e3bab | 2001-01-19 | Per Hedbor | | Thread.Thread t = thread_create(f, @args);
|
666412 | 2001-02-23 | Per Hedbor | | name_thread( t, id );
|
4f4bc1 | 1998-02-04 | Per Hedbor | | return t;
}
|
676f58 | 2000-03-24 | Per Hedbor | |
class Queue
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
03aa46 | 2002-10-01 | Martin Stjernholm | |
|
676f58 | 2000-03-24 | Per Hedbor | | {
inherit Thread.Condition : r_cond;
array buffer=allocate(8);
int r_ptr, w_ptr;
int size()
{
return w_ptr - r_ptr;
}
mixed read()
{
|
8140af | 2002-10-27 | Martin Stjernholm | | while(!(w_ptr - r_ptr)) {
|
291cf0 | 2002-10-23 | Martin Stjernholm | |
|
8140af | 2002-10-27 | Martin Stjernholm | |
Thread.Mutex m = Thread.Mutex();
r_cond::wait (m->lock());
}
|
676f58 | 2000-03-24 | Per Hedbor | | mixed tmp = buffer[r_ptr];
buffer[r_ptr++] = 0;
return tmp;
}
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
mixed tryread()
{
if (!(w_ptr - r_ptr)) return ([])[0];
mixed tmp = buffer[r_ptr];
buffer[r_ptr++] = 0;
return tmp;
}
|
164a58 | 2003-04-14 | Martin Stjernholm | |
|
676f58 | 2000-03-24 | Per Hedbor | | void write(mixed v)
{
if(w_ptr >= sizeof(buffer))
{
buffer=buffer[r_ptr..]+allocate(8);
w_ptr-=r_ptr;
r_ptr=0;
}
buffer[w_ptr++]=v;
r_cond::signal();
}
}
|
4c3c53 | 2001-08-09 | Per Hedbor | |
|
8fb517 | 2000-05-27 | Per Hedbor | | local static Queue handle_queue = Queue();
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
172054 | 1998-10-04 | Henrik Grubbström (Grubba) | |
|
8fb517 | 2000-05-27 | Per Hedbor | | local static int thread_reap_cnt;
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
static int threads_on_hold;
|
14179b | 1997-01-29 | Per Hedbor | |
|
8fb517 | 2000-05-27 | Per Hedbor | | local static void handler_thread(int id)
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
14179b | 1997-01-29 | Per Hedbor | | {
|
9567c1 | 2001-02-23 | Martin Stjernholm | | THREAD_WERR("Handle thread ["+id+"] started");
mixed h, q;
|
aa7872 | 2001-08-24 | Martin Stjernholm | | set_u_and_gid (1);
#ifdef TEST_EUID_CHANGE
if (test_euid_change) {
Stdio.File f = Stdio.File();
if (f->open ("rootonly", "r") && f->read())
werror ("Handler thread %d can read rootonly\n", id);
else
werror ("Handler thread %d can't read rootonly\n", id);
}
#endif
|
9567c1 | 2001-02-23 | Martin Stjernholm | | while(1)
|
4f4bc1 | 1998-02-04 | Per Hedbor | | {
|
a11c32 | 2004-05-07 | Martin Stjernholm | | int thread_flagged_as_busy;
|
4f4bc1 | 1998-02-04 | Per Hedbor | | if(q=catch {
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | do {
|
4eb319 | 2001-09-02 | Martin Stjernholm | |
|
bfb4d4 | 1999-12-28 | Martin Nilsson | | THREAD_WERR("Handle thread ["+id+"] waiting for next event");
|
9567c1 | 2001-02-23 | Martin Stjernholm | | if(arrayp(h=handle_queue->read()) && h[0]) {
THREAD_WERR(sprintf("Handle thread [%O] calling %O(%{%O, %})",
id, h[0], h[1] / 1));
|
67f60e | 2000-07-09 | Martin Nilsson | | set_locale();
|
76ae18 | 2001-02-23 | Martin Stjernholm | | busy_threads++;
|
a11c32 | 2004-05-07 | Martin Stjernholm | | thread_flagged_as_busy = 1;
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | h[0](@h[1]);
h=0;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | busy_threads--;
|
a11c32 | 2004-05-07 | Martin Stjernholm | | thread_flagged_as_busy = 0;
|
310710 | 1998-09-01 | Marcus Comstedt | | } else if(!h) {
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | | report_debug("Handle thread ["+id+"] stopped.\n");
|
310710 | 1998-09-01 | Marcus Comstedt | | thread_reap_cnt--;
|
23007b | 2000-05-28 | Martin Nilsson | | #ifdef NSERIOUS
|
10089c | 2000-05-17 | Martin Nilsson | | if(!thread_reap_cnt) report_debug("+++ATH\n");
|
23007b | 2000-05-28 | Martin Nilsson | | #endif
|
310710 | 1998-09-01 | Marcus Comstedt | | return;
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | }
|
9567c1 | 2001-02-23 | Martin Stjernholm | | #ifdef DEBUG
else if (h != 1)
error ("Unknown message in handle_queue: %O\n", h);
#endif
else {
num_hold_messages--;
THREAD_WERR("Handle thread [" + id + "] put on hold");
threads_on_hold++;
|
8140af | 2002-10-27 | Martin Stjernholm | | if (Thread.Condition cond = hold_wakeup_cond) {
|
291cf0 | 2002-10-23 | Martin Stjernholm | |
|
8140af | 2002-10-27 | Martin Stjernholm | |
Thread.Mutex m = Thread.Mutex();
cond->wait (m->lock());
}
|
9567c1 | 2001-02-23 | Martin Stjernholm | | threads_on_hold--;
THREAD_WERR("Handle thread [" + id + "] released");
}
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | } while(1);
}) {
|
a11c32 | 2004-05-07 | Martin Stjernholm | | if (thread_flagged_as_busy)
busy_threads--;
|
774c9e | 2000-01-13 | Henrik Grubbström (Grubba) | | if (h = catch {
|
434bac | 2000-07-14 | Andreas Lange | | report_error(
describe_backtrace(q));
|
774c9e | 2000-01-13 | Henrik Grubbström (Grubba) | | if (q = catch {h = 0;}) {
|
52faaf | 2001-03-28 | Martin Stjernholm | | report_error(LOC_M(5, "Uncaught error in handler thread: %sClient "
|
c8ee71 | 2000-09-09 | Andreas Lange | | "will not get any response from Roxen.")+"\n",
|
67f60e | 2000-07-09 | Martin Nilsson | | describe_backtrace(q));
|
8d3132 | 2001-06-06 | Martin Stjernholm | | catch (q = 0);
|
774c9e | 2000-01-13 | Henrik Grubbström (Grubba) | | }
}) {
catch {
report_error("Error reporting error:\n");
report_error(sprintf("Raw error: %O\n", h[0]));
report_error(sprintf("Original raw error: %O\n", q[0]));
};
|
8d3132 | 2001-06-06 | Martin Stjernholm | | catch (q = 0);
catch (h = 0);
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | }
}
|
4f4bc1 | 1998-02-04 | Per Hedbor | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
68d256 | 2001-01-31 | Per Hedbor | | void handle(function f, mixed ... args)
|
3aaaa7 | 1997-06-12 | Wilhelm Köhler | | {
handle_queue->write(({f, args }));
}
|
14179b | 1997-01-29 | Per Hedbor | | int number_of_threads;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
int busy_threads;
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | static array(object) handler_threads = ({});
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
14179b | 1997-01-29 | Per Hedbor | | void start_handler_threads()
{
|
8552d9 | 2001-01-13 | Martin Nilsson | | if (query("numthreads") <= 1) {
|
7b798d | 2000-07-04 | Per Hedbor | | set( "numthreads", 1 );
|
76ae18 | 2001-02-23 | Martin Stjernholm | | report_warning (LOC_S(1, "Starting one thread to handle requests.")+"\n");
|
23414a | 2000-07-21 | Andreas Lange | | } else {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_notice (LOC_S(2, "Starting %d threads to handle requests.")+"\n",
|
8552d9 | 2001-01-13 | Martin Nilsson | | query("numthreads") );
|
a60c4c | 1997-07-03 | Henrik Grubbström (Grubba) | | }
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | array(object) new_threads = ({});
|
8552d9 | 2001-01-13 | Martin Nilsson | | for(; number_of_threads < query("numthreads"); number_of_threads++)
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | new_threads += ({ do_thread_create( "Handle thread [" +
number_of_threads + "]",
handler_thread, number_of_threads ) });
handler_threads += new_threads;
|
14179b | 1997-01-29 | Per Hedbor | | }
|
06583f | 1997-09-03 | Per Hedbor | |
|
9567c1 | 2001-02-23 | Martin Stjernholm | | static int num_hold_messages;
static Thread.Condition hold_wakeup_cond = Thread.Condition();
|
03aa46 | 2002-10-01 | Martin Stjernholm | |
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
void hold_handler_threads()
{
if (!hold_wakeup_cond) {
THREAD_WERR("Ignoring request to hold handler threads during stop");
return;
}
int timeout=10;
#if constant(_reset_dmalloc)
timeout *= 10;
#endif /* constant(_reset_dmalloc) */
THREAD_WERR("Putting " + (number_of_threads - threads_on_hold) +
" handler threads on hold, " +
threads_on_hold + " on hold already");
for (int i = number_of_threads - threads_on_hold - num_hold_messages; i-- > 0;) {
handle_queue->write (1);
num_hold_messages++;
}
while (threads_on_hold < number_of_threads && timeout--)
sleep (0.1);
THREAD_WERR(threads_on_hold + " handler threads on hold, " +
(number_of_threads - threads_on_hold) + " not responding");
}
void release_handler_threads (int numthreads)
|
1d3260 | 2001-08-13 | Martin Stjernholm | |
|
9567c1 | 2001-02-23 | Martin Stjernholm | | {
if (Thread.Condition cond = hold_wakeup_cond) {
for (int i = handle_queue->size(); i && num_hold_messages; i--) {
mixed task = handle_queue->tryread();
if (task == 1) num_hold_messages--;
else handle_queue->write (task);
}
#ifdef DEBUG
if (num_hold_messages)
error ("num_hold_messages is bogus (%d).\n", num_hold_messages);
#endif
num_hold_messages = 0;
int blocked_threads = number_of_threads - threads_on_hold;
int threads_to_create = numthreads - threads_on_hold;
|
1d3260 | 2001-08-13 | Martin Stjernholm | | THREAD_WERR("Releasing " + threads_on_hold + " threads on hold");
|
9567c1 | 2001-02-23 | Martin Stjernholm | | cond->broadcast();
if (threads_to_create > 0) {
array(object) new_threads = ({});
|
1d3260 | 2001-08-13 | Martin Stjernholm | | for (int n = 0; n < threads_to_create; number_of_threads++, n++)
|
9567c1 | 2001-02-23 | Martin Stjernholm | | new_threads += ({ do_thread_create( "Handle thread [" +
number_of_threads + "]",
handler_thread, number_of_threads ) });
handler_threads += new_threads;
report_notice ("Created %d new handler threads to compensate "
"for %d blocked ones.\n", threads_to_create, blocked_threads);
}
}
else {
THREAD_WERR("Ignoring request to release handler threads during stop");
return;
}
}
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | | static Thread.MutexKey backend_block_lock;
|
310710 | 1998-09-01 | Marcus Comstedt | | void stop_handler_threads()
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | |
|
310710 | 1998-09-01 | Marcus Comstedt | | {
|
95b69e | 1999-09-05 | Per Hedbor | | int timeout=10;
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | #if constant(_reset_dmalloc)
timeout *= 10;
#endif /* constant(_reset_dmalloc) */
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Stopping all request handler threads.\n");
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
if (Thread.Condition cond = hold_wakeup_cond) {
hold_wakeup_cond = 0;
cond->broadcast();
}
|
310710 | 1998-09-01 | Marcus Comstedt | | while(number_of_threads>0) {
number_of_threads--;
handle_queue->write(0);
thread_reap_cnt++;
}
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | handler_threads = ({});
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | |
|
9567c1 | 2001-02-23 | Martin Stjernholm | | if (this_thread() != backend_thread && !backend_block_lock) {
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | | thread_reap_cnt++;
Thread.Mutex mutex = Thread.Mutex();
backend_block_lock = mutex->lock();
call_out (lambda () {
thread_reap_cnt--;
report_debug("Backend thread stopped.\n");
mutex->lock();
error("Backend stop failed.\n");
}, 0);
}
|
310710 | 1998-09-01 | Marcus Comstedt | | while(thread_reap_cnt) {
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | sleep(0.1);
|
310710 | 1998-09-01 | Marcus Comstedt | | if(--timeout<=0) {
|
9567c1 | 2001-02-23 | Martin Stjernholm | | report_debug("Giving up waiting on threads; "
"%d threads blocked.\n", thread_reap_cnt);
#ifdef DEBUG
describe_all_threads();
#endif
|
310710 | 1998-09-01 | Marcus Comstedt | | return;
}
}
}
|
50b58b | 2001-01-31 | Per Hedbor | |
#else
|
68d256 | 2001-01-31 | Per Hedbor | | void handle(function f, mixed ... args)
|
50b58b | 2001-01-31 | Per Hedbor | | {
f(@args);
}
|
4c3c53 | 2001-08-09 | Per Hedbor | | #endif /* THREADS */
|
50b58b | 2001-01-31 | Per Hedbor | | function async_sig_start( function f, int really )
{
class SignalAsyncVerifier( function f )
{
static int async_called;
void really_call( array args )
{
async_called = 0;
f( @args );
}
void call( mixed ... args )
{
|
614622 | 2001-06-24 | Per Hedbor | | if( async_called && async_called-time() )
|
50b58b | 2001-01-31 | Per Hedbor | | {
|
40acb3 | 2002-04-15 | Martin Stjernholm | | report_debug("Received signal %s\n", (string) signame( args[0] ) );
|
50b58b | 2001-01-31 | Per Hedbor | | report_debug("\n\n"
"Async calling failed for %O, calling synchronous\n", f);
report_debug("Backtrace at time of hangup:\n%s\n",
describe_backtrace( backtrace() ));
f( @args );
return;
}
|
20bd1e | 2001-06-24 | Per Hedbor | | if( !async_called )
{
|
40acb3 | 2002-04-15 | Martin Stjernholm | | report_debug("Received signal %s\n", (string) signame( args[0] ) );
|
20bd1e | 2001-06-24 | Per Hedbor | | async_called=time();
call_out( really_call, 0, args );
}
|
50b58b | 2001-01-31 | Per Hedbor | | }
};
if( really > 0 )
return lambda( mixed ... args ){ call_out( f, 0, @args ); };
if( really < 0 )
return f;
return SignalAsyncVerifier( f )->call;
}
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #ifdef THREADS
|
164a58 | 2003-04-14 | Martin Stjernholm | | static Thread.Queue bg_queue = Thread.Queue();
|
76ae18 | 2001-02-23 | Martin Stjernholm | | static int bg_process_running;
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
static constant bg_time_buffer_max = 30;
|
a99a33 | 2004-10-11 | Marcus Wellhardh | | static constant bg_time_buffer_min = 0;
|
8f6382 | 2001-02-27 | Martin Stjernholm | | static int bg_last_busy = 0;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | static void bg_process_queue()
{
if (bg_process_running) return;
bg_process_running = 1;
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
int maxbeats =
min (time() - bg_last_busy, bg_time_buffer_max) * (int) (1 / 0.04);
|
76ae18 | 2001-02-23 | Martin Stjernholm | | if (mixed err = catch {
|
164a58 | 2003-04-14 | Martin Stjernholm | | while (bg_queue->size()) {
array task = bg_queue->read();
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
if (busy_threads > 1) {
for (maxbeats = max (maxbeats, (int) (bg_time_buffer_min / 0.04));
busy_threads > 1 && maxbeats > 0;
maxbeats--)
sleep (0.04);
bg_last_busy = time();
}
|
54671c | 2001-11-12 | Martin Stjernholm | | #ifdef DEBUG_BACKGROUND_RUN
|
a99a33 | 2004-10-11 | Marcus Wellhardh | | report_debug ("background_run run %s (%s) [%d jobs left in queue]\n",
|
54671c | 2001-11-12 | Martin Stjernholm | | functionp (task[0]) ?
|
aa94b4 | 2001-11-21 | Martin Stjernholm | | sprintf ("%s: %s", Function.defined (task[0]),
master()->describe_function (task[0])) :
programp (task[0]) ?
sprintf ("%s: %s", Program.defined (task[0]),
master()->describe_program (task[0])) :
sprintf ("%O", task[0]),
|
54671c | 2001-11-12 | Martin Stjernholm | | map (task[1], lambda (mixed arg)
|
a99a33 | 2004-10-11 | Marcus Wellhardh | | {return sprintf ("%O", arg);}) * ", ",
bg_queue->size());
float task_time = gauge {
#endif
if (task[0])
task[0] (@task[1]);
#ifdef DEBUG_BACKGROUND_RUN
};
report_debug ("background_run done, took %f sec\n", task_time);
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #endif
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
if (busy_threads > 1) bg_last_busy = time();
|
76ae18 | 2001-02-23 | Martin Stjernholm | | }
}) {
bg_process_running = 0;
handle (bg_process_queue);
throw (err);
}
bg_process_running = 0;
}
#endif
void background_run (int|float delay, function func, mixed... args)
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
{
|
164a58 | 2003-04-14 | Martin Stjernholm | | #ifdef DEBUG_BACKGROUND_RUN
|
a99a33 | 2004-10-11 | Marcus Wellhardh | | report_debug ("background_run enqueue %s (%s) [%d jobs in queue]\n",
|
164a58 | 2003-04-14 | Martin Stjernholm | | functionp (func) ?
sprintf ("%s: %s", Function.defined (func),
master()->describe_function (func)) :
programp (func) ?
sprintf ("%s: %s", Program.defined (func),
master()->describe_program (func)) :
sprintf ("%O", func),
map (args, lambda (mixed arg)
|
a99a33 | 2004-10-11 | Marcus Wellhardh | | {return sprintf ("%O", arg);}) * ", ",
bg_queue->size());
|
164a58 | 2003-04-14 | Martin Stjernholm | | #endif
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #ifdef THREADS
if (!hold_wakeup_cond)
return;
|
6e2e5d | 2003-01-20 | Martin Stjernholm | | function enqueue = lambda()
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
bg_queue->write (({func, args}));
|
164a58 | 2003-04-14 | Martin Stjernholm | | if (!bg_process_running)
|
76ae18 | 2001-02-23 | Martin Stjernholm | | handle (bg_process_queue);
};
if (delay)
call_out (enqueue, delay);
else
enqueue();
|
6e2e5d | 2003-01-20 | Martin Stjernholm | | enqueue = 0;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #else
call_out (func, delay, @args);
#endif
}
class BackgroundProcess
|
5ee4b7 | 2004-05-25 | Martin Stjernholm | |
|
0a558e | 2004-10-19 | Martin Stjernholm | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
int|float period;
int stopping = 0;
static void repeat (function func, mixed args)
{
|
5ee4b7 | 2004-05-25 | Martin Stjernholm | |
int self_refs = _refs (this);
#ifdef DEBUG
if (self_refs < 4)
|
0a558e | 2004-10-19 | Martin Stjernholm | | error ("Minimum ref calculation wrong - have only %d refs.\n", self_refs);
|
5ee4b7 | 2004-05-25 | Martin Stjernholm | | #endif
if (stopping || self_refs <= 4) return;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | func (@args);
background_run (period, repeat, func, args);
}
|
d35d5f | 2001-06-13 | Jonas Wallden | |
void set_period (int|float period_)
{
period = period_;
}
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
static void create (int|float period_, function func, mixed... args)
{
period = period_;
background_run (period, repeat, func, args);
}
void stop()
{
stopping = 1;
}
|
54671c | 2001-11-12 | Martin Stjernholm | |
string _sprintf() {return "BackgroundProcess()";}
|
76ae18 | 2001-02-23 | Martin Stjernholm | | }
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
934b3f | 2000-02-04 | Per Hedbor | | mapping get_port_options( string key )
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
934b3f | 2000-02-04 | Per Hedbor | | {
return (query( "port_options" )[ key ] || ([]));
}
void set_port_options( string key, mapping value )
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
934b3f | 2000-02-04 | Per Hedbor | | {
mapping q = query("port_options");
q[ key ] = value;
set( "port_options" , q );
save( );
}
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | #ifdef DEBUG_URL2CONF
#define URL2CONF_MSG(X...) report_debug (X)
#else
#define URL2CONF_MSG(X...)
#endif
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | | static mapping(string:int(0..1)) host_is_local_cache = ([]);
int(0..1) host_is_local(string hostname)
{
int(0..1) res;
if (!zero_type(res = host_is_local_cache[hostname])) return res;
string ip = blocking_host_to_ip(hostname);
Stdio.Port port = Stdio.Port();
|
bfa4d7 | 2005-10-07 | Anders Johansson | |
catch {
res = port->bind(0, 0, ip);
};
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | |
destruct(port);
return host_is_local_cache[hostname] = res;
}
Configuration find_configuration_for_url(Standards.URI url,
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | void|Configuration only_this_conf,
void|array(Protocol) return_port)
|
9ec100 | 2002-10-01 | Anders Johansson | |
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | |
|
6dcf35 | 2002-09-20 | Anders Johansson | | {
Configuration c;
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | Protocol c_portobj;
|
9ec100 | 2002-10-01 | Anders Johansson | | string url_with_port = sprintf("%s://%s:%d%s", url->scheme, url->host,
url->port,
(sizeof(url->path)?url->path:"/"));
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | |
URL2CONF_MSG("URL with port: %s\n", url_with_port);
|
6dcf35 | 2002-09-20 | Anders Johansson | | foreach( indices(urls), string u )
{
mixed q = urls[u];
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | URL2CONF_MSG("Trying %O:%O\n", u, q);
|
9ec100 | 2002-10-01 | Anders Johansson | | if( glob( u+"*", url_with_port ) )
{
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | URL2CONF_MSG("glob match\n");
if( q->port &&
(c = q->port->find_configuration_for_url(url_with_port, 0, 1 )) )
|
6dcf35 | 2002-09-20 | Anders Johansson | | {
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | URL2CONF_MSG("Found config: %O\n", c);
|
9ec100 | 2002-10-01 | Anders Johansson | |
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | | if ((only_this_conf && (c != only_this_conf)) ||
((search(u, "*") != -1 || search(u, "?") != -1) &&
(!host_is_local(url->host)))) {
URL2CONF_MSG("Bad match: only_this_conf:%O, host_is_local:%O\n",
(only_this_conf && (c == only_this_conf)),
(!host_is_local(url->host)));
|
9ec100 | 2002-10-01 | Anders Johansson | | c = 0;
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | | continue;
|
9ec100 | 2002-10-01 | Anders Johansson | | }
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | c_portobj = q->port;
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | | break;
|
6dcf35 | 2002-09-20 | Anders Johansson | | }
|
9ec100 | 2002-10-01 | Anders Johansson | | }
|
6dcf35 | 2002-09-20 | Anders Johansson | | }
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | URL2CONF_MSG("Result: %O\n", c);
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | if (return_port)
return_port[0] = c_portobj;
|
6dcf35 | 2002-09-20 | Anders Johansson | | return c;
}
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | class InternalRequestID
{
inherit RequestID;
|
7ead5a | 2001-08-15 | Per Hedbor | | this_program set_path( string f )
{
|
f49131 | 2004-10-11 | Martin Stjernholm | | raw_url = Roxen.http_encode_invalids( f );
|
8cbc5f | 2002-09-03 | Martin Stjernholm | |
|
7ead5a | 2001-08-15 | Per Hedbor | | if( strlen( f ) > 5 )
{
string a;
switch( f[1] )
{
case '<':
if (sscanf(f, "/<%s>/%s", a, f)==2)
{
config = (multiset)(a/",");
f = "/"+f;
}
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 ) );
|
0a558e | 2004-10-19 | Martin Stjernholm | | return this;
|
7ead5a | 2001-08-15 | Per Hedbor | | }
this_program set_url( string url )
{
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | object uri = Standards.URI(url);
prot = upper_case(uri->scheme);
misc->host = uri->host;
string path = uri->path;
raw_url = path;
|
8cbc5f | 2002-09-03 | Martin Stjernholm | | method = "GET";
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | raw = "GET " + raw_url + " HTTP/1.1\r\n\r\n";
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | array(Protocol) port_array = ({ 0 });
conf = find_configuration_for_url(uri, 0, port_array);
port_obj = port_array[0];
|
8cbc5f | 2002-09-03 | Martin Stjernholm | | return set_path( raw_url );
|
7ead5a | 2001-08-15 | Per Hedbor | | }
static string _sprintf()
{
return sprintf("RequestID(conf=%O; not_query=%O)", conf, not_query );
}
|
b00cae | 2000-09-30 | Per Hedbor | | static void create()
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | {
client = ({ "Roxen" });
prot = "INTERNAL";
method = "GET";
|
99cb5e | 2001-02-05 | Per Hedbor | | real_variables = ([]);
variables = FakedVariables( real_variables );
|
4dd3e0 | 2001-08-17 | Martin Nilsson | | root_id = this_object();
|
99cb5e | 2001-02-05 | Per Hedbor | |
|
bb7b50 | 2003-01-24 | Anders Johansson | | misc = ([ "pref_languages": PrefLanguages(),
"cacheable": INITIAL_CACHEABLE,
]);
|
4410ed | 2003-11-03 | Martin Stjernholm | | connection_misc = ([]);
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | cookies = ([]);
throttle = ([]);
|
db4ca9 | 2000-09-18 | Henrik Grubbström (Grubba) | | client_var = ([]);
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | request_headers = ([]);
prestate = (<>);
config = (<>);
supports = (<>);
pragma = (<>);
rest_query = "";
extra_extension = "";
|
262275 | 2000-11-13 | Marcus Comstedt | | remoteaddr = "127.0.0.1";
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | }
}
|
49284b | 2000-02-17 | Per Hedbor | |
|
c5e096 | 1999-10-04 | Per Hedbor | | class Protocol
|
c09144 | 2000-08-15 | Johan Sundström | |
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
722c9e | 2001-11-07 | Henrik Grubbström (Grubba) | | static Stdio.Port port_obj;
|
934b3f | 2000-02-04 | Per Hedbor | | inherit "basic_defvar";
|
abc59a | 2000-08-23 | Per Hedbor | | int bound;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
5773f6 | 2000-08-27 | Martin Stjernholm | | string path;
|
c5e096 | 1999-10-04 | Per Hedbor | | constant name = "unknown";
constant supports_ipless = 0;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
c5e096 | 1999-10-04 | Per Hedbor | | constant requesthandlerfile = "";
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
c09144 | 2000-08-15 | Johan Sundström | |
|
c5e096 | 1999-10-04 | Per Hedbor | | constant default_port = 4711;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
934b3f | 2000-02-04 | Per Hedbor | |
|
c5e096 | 1999-10-04 | Per Hedbor | | int port;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
c5e096 | 1999-10-04 | Per Hedbor | | string ip;
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
8fb517 | 2000-05-27 | Per Hedbor | | int refs;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
c5e096 | 1999-10-04 | Per Hedbor | | program requesthandler;
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | array(string) sorted_urls = ({});
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | mapping(string:mapping) urls = ([]);
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | mapping(Configuration:mapping) conf_data = ([]);
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | void ref(string name, mapping data)
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | if(urls[name])
|
8fb517 | 2000-05-27 | Per Hedbor | | {
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | conf_data[urls[name]->conf] = urls[name] = data;
|
8fb517 | 2000-05-27 | Per Hedbor | | return;
}
|
5773f6 | 2000-08-27 | Martin Stjernholm | | if (!refs) path = data->path;
else if (path != (data->path || "")) path = 0;
|
c5e096 | 1999-10-04 | Per Hedbor | | refs++;
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | conf_data[data->conf] = urls[name] = data;
sorted_urls = Array.sort_array(indices(urls),
|
24625e | 2000-08-28 | Per Hedbor | | lambda(string a, string b) {
return sizeof(a)<sizeof(b);
});
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
b43d38 | 2002-04-19 | Anders Johansson | | void unref(string _name)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
bc5c2a | 2000-08-23 | Per Hedbor | |
|
5773f6 | 2000-08-27 | Martin Stjernholm | |
|
b43d38 | 2002-04-19 | Anders Johansson | | m_delete(conf_data, urls[_name]->conf);
m_delete(urls, _name);
|
5773f6 | 2000-08-27 | Martin Stjernholm | | if (!path && sizeof (Array.uniq (values (urls)->path)) == 1)
path = values (urls)[0]->path;
|
b43d38 | 2002-04-19 | Anders Johansson | | sorted_urls -= ({_name});
|
f74e25 | 2002-04-24 | Henrik Grubbström (Grubba) | | #ifdef PORT_DEBUG
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | report_debug("Protocol(%s)->unref(%O): refs:%d\n",
get_url(), _name, refs);
|
f74e25 | 2002-04-24 | Henrik Grubbström (Grubba) | | #endif /* PORT_DEBUG */
|
722c9e | 2001-11-07 | Henrik Grubbström (Grubba) | | if( !--refs ) {
|
0830d1 | 2003-11-05 | Henrik Grubbström (Grubba) | | if (retries) {
remove_call_out(bind);
}
|
61d1c3 | 2001-11-27 | Henrik Grubbström (Grubba) | | if (port_obj) {
destruct(port_obj);
}
|
722c9e | 2001-11-07 | Henrik Grubbström (Grubba) | | port_obj = 0;
|
b43d38 | 2002-04-19 | Anders Johansson | | m_delete(open_ports[name][ip], port);
if(!sizeof(open_ports[name][ip]))
m_delete(open_ports[name], ip);
if(!sizeof(open_ports[name]))
m_delete(open_ports, name);
|
722c9e | 2001-11-07 | Henrik Grubbström (Grubba) | |
}
}
Stdio.File accept()
{
return port_obj->accept();
}
string query_address()
{
return port_obj && port_obj->query_address();
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
1550aa | 2000-08-12 | Per Hedbor | | mapping mu;
|
851483 | 2000-11-27 | Per Hedbor | | string rrhf;
|
8fb517 | 2000-05-27 | Per Hedbor | | static void got_connection()
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
3e3bab | 2001-01-19 | Per Hedbor | | Stdio.File q = accept( );
|
8fb517 | 2000-05-27 | Per Hedbor | | if( q )
|
1550aa | 2000-08-12 | Per Hedbor | | {
|
851483 | 2000-11-27 | Per Hedbor | | if( !requesthandler )
{
requesthandler = (program)(rrhf);
}
|
3e3bab | 2001-01-19 | Per Hedbor | | Configuration c;
|
24625e | 2000-08-28 | Per Hedbor | | if( refs < 2 )
|
1550aa | 2000-08-12 | Per Hedbor | | {
if(!mu)
{
mu = urls[sorted_urls[0]];
|
1f4a6c | 2000-08-28 | Per Hedbor | | if(!(c=mu->conf)->inited )
c->enable_all_modules();
} else
c = mu->conf;
|
1550aa | 2000-08-12 | Per Hedbor | | }
requesthandler( q, this_object(), c );
}
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | }
|
8fb517 | 2000-05-27 | Per Hedbor | | local function sp_fcfu;
|
4c8777 | 2000-08-11 | Per Hedbor | |
|
7bc738 | 2002-08-19 | Henrik Grubbström (Grubba) | | #define INIT(X) do{ \
mapping _=(X); \
string __=_->path; \
c=_->conf; \
if(__&&id->adjust_for_config_path) \
id->adjust_for_config_path(__); \
if(!c->inited) \
c->enable_all_modules(); \
} while(0)
|
347c72 | 2000-08-31 | Per Hedbor | |
|
9a8a15 | 2000-09-25 | Per Hedbor | | Configuration find_configuration_for_url( string url, RequestID id,
int|void no_default )
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | {
|
9a8a15 | 2000-09-25 | Per Hedbor | | Configuration c;
|
09d038 | 2003-04-14 | Henrik Grubbström (Grubba) | | if( sizeof( urls ) == 1 && !no_default)
|
4c8777 | 2000-08-11 | Per Hedbor | | {
|
347c72 | 2000-08-31 | Per Hedbor | | if(!mu) mu=urls[sorted_urls[0]];
INIT( mu );
|
a11c32 | 2004-05-07 | Martin Stjernholm | | URL2CONF_MSG ("%O %O Only one configuration: %O\n", this_object(), url, c);
|
4c8777 | 2000-08-11 | Per Hedbor | | return c;
|
3d18ba | 2001-12-19 | Henrik Grubbström (Grubba) | | } else if (!sizeof(sorted_urls)) {
URL2CONF_MSG("%O %O No active URLS!\n", this_object(), url);
return 0;
|
4c8777 | 2000-08-11 | Per Hedbor | | }
url = lower_case( url );
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | URL2CONF_MSG("sorted_urls: %O\n"
"url: %O\n", sorted_urls, url);
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | foreach( sorted_urls, string in )
{
if( glob( in+"*", url ) )
{
|
347c72 | 2000-08-31 | Per Hedbor | | INIT( urls[in] );
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | URL2CONF_MSG ("%O %O sorted_urls: %O\n", this_object(), url, c);
|
1d7d6d | 2000-02-16 | Per Hedbor | | return c;
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | }
}
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | if( no_default ) {
URL2CONF_MSG ("%O %O no default\n", this_object(), url);
|
8fb517 | 2000-05-27 | Per Hedbor | | return 0;
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | }
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
347c72 | 2000-08-31 | Per Hedbor | |
|
2ad7d0 | 2000-03-27 | Per Hedbor | | mixed i;
|
347c72 | 2000-08-31 | Per Hedbor | | if( !functionp(sp_fcfu) && ( i=open_ports[ name ][ 0 ][ port ] ) )
|
8fb517 | 2000-05-27 | Per Hedbor | | sp_fcfu = i->find_configuration_for_url;
|
347c72 | 2000-08-31 | Per Hedbor | | if( sp_fcfu && (sp_fcfu != find_configuration_for_url)
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | && (i = sp_fcfu( url, id, 1 ))) {
URL2CONF_MSG ("%O %O sp_fcfu: %O\n", this_object(), url, i);
|
7120b8 | 2000-03-27 | Per Hedbor | | return i;
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | }
|
8fb517 | 2000-05-27 | Per Hedbor | |
multiset choices = (< >);
|
d09399 | 2000-09-25 | Per Hedbor | | foreach( configurations, Configuration c )
|
8fb517 | 2000-05-27 | Per Hedbor | | if( c->query( "default_server" ) )
choices |= (< c >);
if( sizeof( choices ) )
|
7120b8 | 2000-03-27 | Per Hedbor | | {
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
347c72 | 2000-08-31 | Per Hedbor | | foreach( values(urls), mapping cc )
if( choices[ cc->conf ] )
|
8fb517 | 2000-05-27 | Per Hedbor | | {
|
347c72 | 2000-08-31 | Per Hedbor | | INIT( cc );
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | URL2CONF_MSG ("%O %O conf in choices: %O\n", this_object(), url, c);
|
347c72 | 2000-08-31 | Per Hedbor | | return c;
|
8fb517 | 2000-05-27 | Per Hedbor | | }
|
347c72 | 2000-08-31 | Per Hedbor | |
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
347c72 | 2000-08-31 | Per Hedbor | |
|
1a231e | 2000-06-04 | Martin Nilsson | | c = ((array)choices)[0];
if(!c->inited) c->enable_all_modules();
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | URL2CONF_MSG ("%O %O any in choices: %O\n", this_object(), url, c);
|
1a231e | 2000-06-04 | Martin Nilsson | | return c;
|
7120b8 | 2000-03-27 | Per Hedbor | | }
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
347c72 | 2000-08-31 | Per Hedbor | | INIT( urls[sorted_urls[0]] );
|
8fb517 | 2000-05-27 | Per Hedbor | | id->misc->defaulted=1;
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | URL2CONF_MSG ("%O %O first in sorted_urls: %O\n", this_object(), url, c);
|
8fb517 | 2000-05-27 | Per Hedbor | | return c;
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
934b3f | 2000-02-04 | Per Hedbor | | mixed query_option( string x )
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
10bdc5 | 1999-10-08 | Henrik Grubbström (Grubba) | | {
|
934b3f | 2000-02-04 | Per Hedbor | | return query( x );
|
10bdc5 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
934b3f | 2000-02-04 | Per Hedbor | | string get_key()
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | |
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (ip == "::")
return name + ":0:" + port;
else
return name+":"+ip+":"+port;
}
string get_url()
{
return (string) name + "://" +
(!ip ? "*" : has_value (ip, ":") ? "[" + ip + "]" : ip) +
":" + port + "/";
|
934b3f | 2000-02-04 | Per Hedbor | | }
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
934b3f | 2000-02-04 | Per Hedbor | | void save()
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
934b3f | 2000-02-04 | Per Hedbor | | {
set_port_options( get_key(),
mkmapping( indices(variables),
map(indices(variables),query)));
}
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
934b3f | 2000-02-04 | Per Hedbor | | void restore()
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
934b3f | 2000-02-04 | Per Hedbor | | {
foreach( (array)get_port_options( get_key() ), array kv )
set( kv[0], kv[1] );
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | static int retries;
static void bind()
{
if (bound) return;
if (!port_obj) port_obj = Stdio.Port();
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | Privs privs = Privs (sprintf ("Binding %s", get_url()));
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | if (port_obj->bind(port, got_connection, ip))
{
|
537a59 | 2005-02-10 | Martin Stjernholm | | privs = 0;
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | bound = 1;
return;
}
|
537a59 | 2005-02-10 | Martin Stjernholm | | privs = 0;
|
eecdf1 | 2005-02-23 | Henrik Grubbström (Grubba) | | #if constant(System.EAFNOSUPPORT)
if (port_obj->errno() == System.EAFNOSUPPORT) {
error("Invalid address " + ip);
}
#endif /* System.EAFNOSUPPORT */
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | report_error(LOC_M(6, "Failed to bind %s (%s)")+"\n",
get_url(), strerror(port_obj->errno()));
#if 0
|
537a59 | 2005-02-10 | Martin Stjernholm | | werror (describe_backtrace (backtrace()));
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | #endif
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | #if constant(System.EADDRINUSE) || constant(system.EADDRINUSE)
if (
#if constant(System.EADDRINUSE)
|
e8cd60 | 2003-11-05 | Henrik Grubbström (Grubba) | | (port_obj->errno() == System.EADDRINUSE) &&
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | #else /* !constant(System.EADDRINUSE) */
|
e8cd60 | 2003-11-05 | Henrik Grubbström (Grubba) | | (port_obj->errno() == system.EADDRINUSE) &&
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | #endif /* constant(System.EADDRINUSE) */
(retries++ < 10)) {
|
3f4044 | 2004-02-03 | Anders Johansson | | report_notice(LOC_M(62, "Attempt %d. Retrying in 1 minute.")+"\n",
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | retries);
call_out(bind, 60);
}
#endif /* constant(System.EADDRINUSE) || constant(system.EADDRINUSE) */
}
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | | static array(int) get_ipv6_sequence(string partition)
{
array(int) segments = ({});
foreach(partition/":", string part) {
if (has_value(part, ".")) {
array(int) sub_segs = array_sscanf(part, "%d.%d.%d.%d");
switch(sizeof(sub_segs)) {
default:
case 4:
segments += ({ sub_segs[0]*256+sub_segs[1],
sub_segs[2]*256+sub_segs[3] });
break;
case 3:
segments += ({ sub_segs[0]*256+sub_segs[1],
sub_segs[2] });
break;
case 2:
segments += ({ sub_segs[0]*256 + sub_segs[1]>>16,
sub_segs[1]&0xffff });
break;
}
} else {
segments += array_sscanf(part, "%x");
}
}
return segments;
}
string canonical_ip(string i)
{
|
157e6e | 2005-03-07 | Martin Stjernholm | | if (!i) return 0;
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | | if (has_value(i, ":")) {
if (i == "::") return "::";
array(string) partitions = i/"::";
array(int) sections = get_ipv6_sequence(partitions[0]);
if (sizeof(partitions) > 1) {
array(int) tail = get_ipv6_sequence(partitions[1]);
sections += allocate(8 - sizeof(sections) - sizeof(tail)) + tail;
} else if (sizeof(sections) < 8) {
sections += allocate(8 - sizeof(sections));
}
i = sprintf("%04.4x:%04.4x:%04.4x:%04.4x:"
"%04.4x:%04.4x:%04.4x:%04.4x",
@sections);
if (i == "0000:0000:0000:0000:0000:0000:0000:0000") return "::";
partitions = i/":";
int start;
int max;
int best;
foreach(partitions + ({ "SENTINEL" }); int ind; string part) {
if (part != "0000") {
if ((ind - start) > max) {
best = start;
max = ind - start;
}
start = ind + 1;
}
}
if (max) {
i = (partitions[..best-1] + ({""}) + partitions[best+max..])*":";
if (!best) i = ":" + i;
if (best + max == 8) i += ":";
}
return i;
} else {
array(int) segments = array_sscanf(i, "%d.%d.%d.%d");
string bytes;
switch(sizeof(segments)) {
default:
case 4:
bytes = sprintf("%1c%1c%1c%1c", @segments);
break;
case 0: return 0;
case 1:
bytes = sprintf("%4c", @segments);
break;
case 2:
bytes = sprintf("%1c%3c", @segments);
break;
case 3:
bytes = sprintf("%1c%1c%2c", @segments);
break;
}
if (bytes == "\0\0\0\0") return 0;
return sprintf("%d.%d.%d.%d", @((array(int))bytes));
}
}
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | static void setup (int pn, string i)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
934b3f | 2000-02-04 | Per Hedbor | | port = pn;
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | | ip = canonical_ip(i);
|
934b3f | 2000-02-04 | Per Hedbor | |
restore();
|
851483 | 2000-11-27 | Per Hedbor | | if( file_stat( "../local/"+requesthandlerfile ) )
rrhf = "../local/"+requesthandlerfile;
else
rrhf = requesthandlerfile;
DDUMP( rrhf );
#ifdef DEBUG
|
c5e096 | 1999-10-04 | Per Hedbor | | if( !requesthandler )
|
851483 | 2000-11-27 | Per Hedbor | | requesthandler = (program)(rrhf);
#endif
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | bound = 0;
port_obj = 0;
retries = 0;
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | }
static void create( int pn, string i )
{
setup (pn, i);
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | bind();
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
8fb517 | 2000-05-27 | Per Hedbor | | static string _sprintf( )
|
b6fb05 | 1999-11-02 | Per Hedbor | | {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | return "Protocol(" + get_url() + ")";
|
b6fb05 | 1999-11-02 | Per Hedbor | | }
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
4820e0 | 1999-07-27 | Henrik Grubbström (Grubba) | |
|
b8fd5c | 2000-09-28 | Per Hedbor | | #if constant(SSL.sslfile)
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | class SSLProtocol
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | {
inherit Protocol;
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | SSL.context ctx = SSL.context();
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | int cert_failure;
static void cert_err_unbind()
{
if (bound) {
port_obj->close();
report_warning ("TLS port %s closed.\n", get_url());
bound = 0;
}
}
#define CERT_WARNING(VAR, MSG, ARGS...) do { \
string msg = (MSG); \
array args = ({ARGS}); \
if (sizeof (args)) msg = sprintf (msg, @args); \
report_warning ("TLS port %s: %s", get_url(), msg); \
(VAR)->add_warning (msg); \
} while (0)
#define CERT_ERROR(VAR, MSG, ARGS...) do { \
string msg = (MSG); \
array args = ({ARGS}); \
if (sizeof (args)) msg = sprintf (msg, @args); \
report_error ("TLS port %s: %s", get_url(), msg); \
(VAR)->add_warning (msg); \
cert_err_unbind(); \
cert_failure = 1; \
return; \
} while (0)
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | void certificates_changed(Variable|void ignored)
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | int old_cert_failure = cert_failure;
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | string raw_keydata;
array(string) certificates = ({});
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | array(object) decoded_certs = ({});
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | Variable Certificates = getvar("ssl_cert_file");
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
d0a4f8 | 2001-04-18 | Per Hedbor | | object privs = Privs("Reading cert file");
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | foreach(map(Certificates->query(), String.trim_whites), string cert_file) {
string raw_cert;
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | SSL3_WERR (sprintf ("Reading cert file %O", cert_file));
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | if( catch{ raw_cert = lopen(cert_file, "r")->read(); } )
|
d0a4f8 | 2001-04-18 | Per Hedbor | | {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | CERT_WARNING (Certificates,
LOC_M(8, "Reading certificate file %O failed: %s\n"),
cert_file, strerror (errno()));
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | continue;
|
d0a4f8 | 2001-04-18 | Per Hedbor | | }
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | object msg = Tools.PEM.pem_msg()->init( raw_cert );
object part = msg->parts["CERTIFICATE"] ||
msg->parts["X509 CERTIFICATE"];
|
d0a4f8 | 2001-04-18 | Per Hedbor | | string cert;
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | if (msg->parts["RSA PRIVATE KEY"] ||
msg->parts["DSA PRIVATE KEY"]) {
raw_keydata = raw_cert;
}
|
d0a4f8 | 2001-04-18 | Per Hedbor | | if (!part || !(cert = part->decoded_body()))
|
2dd46b | 2000-03-24 | Per Hedbor | | {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | CERT_WARNING (Certificates,
LOC_M(10, "No certificate found in %O.\n"),
cert_file);
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | continue;
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | certificates += ({ cert });
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | |
object tbs = Tools.X509.decode_certificate (cert);
if (!tbs) {
CERT_WARNING (Certificates,
LOC_M(13, "Certificate not valid (DER).\n"));
continue;
}
decoded_certs += ({tbs});
}
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (!sizeof(decoded_certs)) {
report_error ("TLS port %s: %s", get_url(),
LOC_M (0,"No certificates found.\n"));
cert_err_unbind();
cert_failure = 1;
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | return;
}
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | Variable KeyFile = getvar("ssl_key_file");
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if( strlen(KeyFile->query())) {
SSL3_WERR (sprintf ("Reading key file %O", KeyFile->query()));
if (catch{ raw_keydata = lopen(KeyFile->query(), "r")->read(); } )
CERT_ERROR (KeyFile,
LOC_M(9, "Reading key file %O failed: %s\n"),
KeyFile->query(), strerror (errno()));
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | }
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | else
KeyFile = Certificates;
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | privs = 0;
if (!raw_keydata)
CERT_ERROR (KeyFile, LOC_M (17,"No private key found.\n"));
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | object msg = Tools.PEM.pem_msg()->init( raw_keydata );
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | SSL3_WERR(sprintf("key file contains: %O", indices(msg->parts)));
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | object part;
if (part = msg->parts["RSA PRIVATE KEY"])
{
string key;
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (!(key = part->decoded_body()))
CERT_ERROR (KeyFile,
LOC_M(11,"Private rsa key not valid")+" (PEM).\n");
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | object rsa = Standards.PKCS.RSA.parse_private_key(key);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (!rsa)
CERT_ERROR (KeyFile,
LOC_M(11,"Private rsa key not valid")+" (DER).\n");
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->rsa = rsa;
SSL3_WERR(sprintf("RSA key size: %d bits", rsa->rsa_size()));
if (rsa->rsa_size() > 512)
{
#if constant(Crypto.RSA)
ctx->short_rsa = Crypto.RSA()->generate_key(512, ctx->random);
#else
ctx->short_rsa = Crypto.rsa()->generate_key(512, ctx->random);
#endif
}
ctx->rsa_mode();
array(int) key_matches =
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | map(decoded_certs,
lambda (object tbs) {
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | return tbs->public_key->rsa->public_key_equal (rsa);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | });
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
int num_key_matches;
array(string) new_certificates = allocate(sizeof(certificates));
int i,j;
for (i=0; i < sizeof(certificates); i++) {
if (key_matches[i]) {
new_certificates[j++] = certificates[i];
num_key_matches++;
|
d0a4f8 | 2001-04-18 | Per Hedbor | | }
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | }
for (i=0; i < sizeof(certificates); i++) {
if (!key_matches[i]) {
new_certificates[j++] = certificates[i];
|
1e7b6f | 2002-01-31 | Jens Larsson | | }
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | if( !num_key_matches )
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | CERT_ERROR (KeyFile,
LOC_M(14, "Certificate and private key do not match.\n"));
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->certificates = new_certificates;
}
else if (part = msg->parts["DSA PRIVATE KEY"])
{
string key;
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (!(key = part->decoded_body()))
CERT_ERROR (KeyFile,
LOC_M(15,"Private dsa key not valid")+" (PEM).\n");
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | object dsa = Standards.PKCS.DSA.parse_private_key(key);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (!dsa)
CERT_ERROR (KeyFile,
LOC_M(15,"Private dsa key not valid")+" (DER).\n");
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | SSL3_WERR(sprintf("Using DSA key."));
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
ctx->dsa = dsa;
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | #if constant(SSL.Cipher)
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->dh_params = SSL.Cipher.DHParameters();
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | #else
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->dh_params = SSL.cipher()->dh_parameters();
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | #endif
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->dhe_dss_mode();
|
d0a4f8 | 2001-04-18 | Per Hedbor | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
|
1e7b6f | 2002-01-31 | Jens Larsson | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | ctx->certificates = certificates;
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | else
CERT_ERROR (KeyFile, LOC_M(17,"No private key found.\n"));
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | #if EXPORT
ctx->export_mode();
#endif
|
fe1c13 | 2005-05-25 | Martin Stjernholm | |
if (!bound) {
bind();
if (old_cert_failure && bound)
report_notice (LOC_M (0, "TLS port %s opened.\n"), get_url());
}
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | }
class CertificateListVariable
{
inherit Variable.FileList;
string doc()
{
return sprintf(::doc() + "\n",
combine_path(getcwd(), "../local"),
getcwd());
}
}
class KeyFileVariable
{
inherit Variable.String;
string doc()
{
return sprintf(::doc() + "\n",
combine_path(getcwd(), "../local"),
getcwd());
}
}
RoxenSSLFile accept()
{
Stdio.File q = ::accept();
if (q)
return RoxenSSLFile (q, ctx);
return 0;
}
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | static void bind()
{
if (!ctx->certificates) return;
::bind();
}
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | void create(int pn, string i)
{
#if constant(Crypto.Random.random_string)
ctx->random = Crypto.Random.random_string;
#else
ctx->random = Crypto.randomness.reasonably_random()->read;
#endif
set_up_ssl_variables( this_object() );
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | ::setup(pn, i);
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
certificates_changed();
|
fe1c13 | 2005-05-25 | Martin Stjernholm | |
getvar ("ssl_cert_file")->set_changed_callback (certificates_changed);
getvar ("ssl_key_file")->set_changed_callback (certificates_changed);
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
b8fd5c | 2000-09-28 | Per Hedbor | |
|
b6fb05 | 1999-11-02 | Per Hedbor | | string _sprintf( )
{
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | return "SSLProtocol(" + get_url() + ")";
|
b6fb05 | 1999-11-02 | Per Hedbor | | }
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | }
|
b8fd5c | 2000-09-28 | Per Hedbor | | #endif
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | |
|
0d0e95 | 2000-11-13 | Per Hedbor | | mapping(string:Protocol) build_protocols_mapping()
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | mapping protocols = ([]);
int st = gethrtime();
|
56509c | 2001-06-30 | Martin Stjernholm | | report_debug("Protocol handlers ... \b");
|
0d0e95 | 2000-11-13 | Per Hedbor | | #ifndef DEBUG
class lazy_load( string prog, string name )
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | program real;
static void realize()
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | if( catch {
|
851483 | 2000-11-27 | Per Hedbor | | DDUMP( prog );
|
0d0e95 | 2000-11-13 | Per Hedbor | | real = (program)prog;
protocols[name] = real;
} )
report_error("Failed to compile protocol handler for "+name+"\n");
|
761baa | 1999-12-08 | Per Hedbor | | }
|
0d0e95 | 2000-11-13 | Per Hedbor | | Protocol `()(mixed ... x)
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | if(!real) realize();
return real(@x);
};
mixed `->( string x )
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | if(!real) realize();
return predef::`->(real, x);
|
761baa | 1999-12-08 | Per Hedbor | | }
|
0d0e95 | 2000-11-13 | Per Hedbor | | };
#endif
foreach( glob( "prot_*.pike", get_dir("protocols") ), string s )
|
6796aa | 1999-12-11 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | sscanf( s, "prot_%s.pike", s );
#if !constant(SSL.sslfile)
switch( s )
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | case "https":
case "ftps":
continue;
|
761baa | 1999-12-08 | Per Hedbor | | }
|
0d0e95 | 2000-11-13 | Per Hedbor | | #endif
|
56509c | 2001-06-30 | Martin Stjernholm | | report_debug( "\b%s \b", s );
|
6f72d4 | 2000-02-08 | Per Hedbor | |
|
0d0e95 | 2000-11-13 | Per Hedbor | | catch
|
761baa | 1999-12-08 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | #ifdef DEBUG
protocols[ s ] = (program)("protocols/prot_"+s+".pike");
#else
protocols[ s ] = lazy_load( ("protocols/prot_"+s+".pike"),s );
|
761baa | 1999-12-08 | Per Hedbor | | #endif
|
0d0e95 | 2000-11-13 | Per Hedbor | | };
|
934b3f | 2000-02-04 | Per Hedbor | | }
|
0d0e95 | 2000-11-13 | Per Hedbor | | foreach( glob("prot_*.pike",get_dir("../local/protocols")||({})), string s )
|
1d7d6d | 2000-02-16 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | sscanf( s, "prot_%s.pike", s );
#if !constant(SSL.sslfile)
switch( s )
|
1d7d6d | 2000-02-16 | Per Hedbor | | {
|
0d0e95 | 2000-11-13 | Per Hedbor | | case "https":
case "ftps":
continue;
|
df36c6 | 1999-10-08 | Henrik Grubbström (Grubba) | | }
|
b8fd5c | 2000-09-28 | Per Hedbor | | #endif
|
56509c | 2001-06-30 | Martin Stjernholm | | report_debug( "\b%s \b", s );
|
0d0e95 | 2000-11-13 | Per Hedbor | | catch {
#ifdef DEBUG
protocols[ s ] = (program)("../local/protocols/prot_"+s+".pike");
|
761baa | 1999-12-08 | Per Hedbor | | #else
|
0d0e95 | 2000-11-13 | Per Hedbor | | protocols[ s ] = lazy_load( ("../local/protocols/prot_"+s+".pike"),s );
|
761baa | 1999-12-08 | Per Hedbor | | #endif
|
0d0e95 | 2000-11-13 | Per Hedbor | | };
}
|
56509c | 2001-06-30 | Martin Stjernholm | | report_debug("\bDone [%.1fms]\n", (gethrtime()-st)/1000.0 );
|
0d0e95 | 2000-11-13 | Per Hedbor | | return protocols;
}
|
b00cae | 2000-09-30 | Per Hedbor | |
|
479d8a | 1999-11-25 | Henrik Grubbström (Grubba) | |
|
0d0e95 | 2000-11-13 | Per Hedbor | | mapping protocols;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | |
mapping(string:mapping(string:mapping(int:Protocol))) open_ports = ([ ]);
|
585789 | 2002-06-27 | Martin Stjernholm | | mapping(string:mapping(string:Configuration)) urls = ([]);
|
c5e096 | 1999-10-04 | Per Hedbor | | array sorted_urls = ({});
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | array(string) find_ips_for( string what )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
c5e096 | 1999-10-04 | Per Hedbor | | if( what == "*" || lower_case(what) == "any" )
|
0c1282 | 2005-03-10 | Henrik Grubbström (Grubba) | | return ({ 0,
|
c86a47 | 2005-11-14 | Martin Stjernholm | | #if constant(__ROXEN_SUPPORTS_IPV6__)
|
0c1282 | 2005-03-10 | Henrik Grubbström (Grubba) | | "::",
#endif /* __ROXEN_SUPPORTS_IPV6__ */
});
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
15635b | 1999-10-10 | Per Hedbor | | if( is_ip( what ) )
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | return ({ what });
|
f99915 | 2005-03-30 | Henrik Grubbström (Grubba) | | else if (what[0] == '[' && what[-1] == ']') {
return ({ what[1..sizeof(what)-2] });
} else if (has_suffix(lower_case(what), ".ipv6")) {
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | |
return ({ replace(what[..sizeof(what)-6], "-", ":") });
}
|
c5e096 | 1999-10-04 | Per Hedbor | | array res = gethostbyname( what );
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | if( res && sizeof( res[1] ) )
|
92898c | 1999-10-10 | Marcus Comstedt | | return Array.uniq(res[1]);
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | |
report_error(LOC_M(46, "Cannot possibly bind to %O, that host is "
"unknown. Substituting with ANY")+"\n", what);
return 0;
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | string normalize_url(string url)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | if (!sizeof (url - " " - "\t")) return "";
|
8fb517 | 2000-05-27 | Per Hedbor | | url = lower_case( url );
|
21182a | 2001-10-05 | Per Hedbor | | Standards.URI ui = Standards.URI(url);
ui->fragment = 0;
url = (string)ui;
|
bc5c2a | 2000-08-23 | Per Hedbor | | url = replace( url, "/ANY", "/*" );
url = replace( url, "/any", "/*" );
|
21182a | 2001-10-05 | Per Hedbor | |
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | string host, path, protocol;
|
bc5c2a | 2000-08-23 | Per Hedbor | | sscanf( url, "%[^:]://%[^/]%s", protocol, host, path );
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | if (!host || !stringp(host)) return "";
if (!protocols[ protocol ]) return "";
int port;
|
bc5c2a | 2000-08-23 | Per Hedbor | | sscanf(host, "%[^:]:%d", host, port);
if( !port )
{
port = protocols[ protocol ]->default_port;
url = protocol+"://"+host+":"+port+path;
}
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | return url;
}
void unregister_url(string url, Configuration conf)
{
string ourl = url;
if (!sizeof(url = normalize_url(url))) return;
|
bc5c2a | 2000-08-23 | Per Hedbor | |
|
e7e603 | 1999-11-05 | Per Hedbor | | report_debug("Unregister "+url+"\n");
|
0aee22 | 2000-08-15 | Martin Stjernholm | |
|
9c3c6c | 2001-11-09 | Henrik Grubbström (Grubba) | | if (urls[url] && (!conf || !urls[url]->conf || (urls[url]->conf == conf)) &&
urls[url]->port)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | urls[ url ]->port->unref(url);
|
c5e096 | 1999-10-04 | Per Hedbor | | m_delete( urls, url );
|
03aa49 | 2000-08-23 | Per Hedbor | | m_delete( urls, ourl );
|
c5e096 | 1999-10-04 | Per Hedbor | | sort_urls();
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
}
|
934b3f | 2000-02-04 | Per Hedbor | | array all_ports( )
{
|
f04752 | 2000-09-25 | Per Hedbor | | return Array.uniq( values( urls )->port )-({0});
|
934b3f | 2000-02-04 | Per Hedbor | | }
Protocol find_port( string name )
{
foreach( all_ports(), Protocol p )
if( p->get_key() == name )
return p;
}
|
c5e096 | 1999-10-04 | Per Hedbor | | void sort_urls()
|
1668b2 | 1998-04-23 | Henrik Grubbström (Grubba) | | {
|
c5e096 | 1999-10-04 | Per Hedbor | | sorted_urls = indices( urls );
sort( map( map( sorted_urls, strlen ), `-), sorted_urls );
|
1668b2 | 1998-04-23 | Henrik Grubbström (Grubba) | | }
|
d09399 | 2000-09-25 | Per Hedbor | | int register_url( string url, Configuration conf )
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
03aa49 | 2000-08-23 | Per Hedbor | | string ourl = url;
|
8fb517 | 2000-05-27 | Per Hedbor | | url = lower_case( url );
|
1e3cd5 | 2000-02-02 | Martin Stjernholm | | if (!sizeof (url - " " - "\t")) return 1;
|
c5e096 | 1999-10-04 | Per Hedbor | | string protocol;
string host;
int port;
string path;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
21182a | 2001-10-05 | Per Hedbor | | Standards.URI ui = Standards.URI(url);
mapping opts = ([]);
string a, b;
foreach( (ui->fragment||"")/";", string x )
{
sscanf( x, "%s=%s", a, b );
opts[a]=b;
}
ui->fragment = 0;
url = (string)ui;
if( (int)opts->nobind )
{
report_warning(
|
55c052 | 2001-11-07 | Henrik Grubbström (Grubba) | | LOC_M(61,"Not binding the port %O, disabled in configuration")+"\n",
|
21182a | 2001-10-05 | Per Hedbor | | url );
return 0;
}
|
ac76fc | 1999-10-07 | Henrik Grubbström (Grubba) | | url = replace( url, "/ANY", "/*" );
url = replace( url, "/any", "/*" );
|
c5e096 | 1999-10-04 | Per Hedbor | |
sscanf( url, "%[^:]://%[^/]%s", protocol, host, path );
|
228fea | 2000-02-15 | Leif Stensson | | if (!host || !stringp(host))
{
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(19,"Bad URL '%s' for server `%s'")+"\n",
|
23414a | 2000-07-21 | Andreas Lange | | url, conf->query_name());
|
abc59a | 2000-08-23 | Per Hedbor | | return 0;
|
228fea | 2000-02-15 | Leif Stensson | | }
|
b8fd5c | 2000-09-28 | Per Hedbor | |
if( !protocols[ protocol ] )
{
|
55a866 | 2000-11-20 | Per Hedbor | | report_error(LOC_M(7,"The protocol '%s' is not available")+"\n", protocol);
|
b8fd5c | 2000-09-28 | Per Hedbor | | return 0;
}
|
228fea | 2000-02-15 | Leif Stensson | | sscanf(host, "%[^:]:%d", host, port);
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
38c507 | 2000-02-28 | Per Hedbor | | if( !port )
{
port = protocols[ protocol ]->default_port;
url = protocol+"://"+host+":"+port+path;
}
|
c5e096 | 1999-10-04 | Per Hedbor | | if( strlen( path ) && ( path[-1] == '/' ) )
path = path[..strlen(path)-2];
if( !strlen( path ) )
path = 0;
|
f034ab | 2001-04-17 | Per Hedbor | | if( urls[ url ] )
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
f034ab | 2001-04-17 | Per Hedbor | | if( !urls[ url ]->port )
m_delete( urls, url );
else if( urls[ url ]->conf )
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
f034ab | 2001-04-17 | Per Hedbor | | if( urls[ url ]->conf != conf )
{
report_error(LOC_M(20,
"Cannot register URL %s, "
"already registered by %s!")+"\n",
url, urls[ url ]->conf->name);
return 0;
}
urls[ url ]->port->ref(url, urls[url]);
return 1;
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
f034ab | 2001-04-17 | Per Hedbor | | else
urls[ url ]->port->unref( url );
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | Protocol prot;
|
c5e096 | 1999-10-04 | Per Hedbor | | if( !( prot = protocols[ protocol ] ) )
{
|
49cd28 | 2000-08-11 | Andreas Lange | | report_error(LOC_M(21, "Cannot register URL %s, "
|
c8ee71 | 2000-09-09 | Andreas Lange | | "cannot find the protocol %s!")+"\n",
|
23414a | 2000-07-21 | Andreas Lange | | url, protocol);
|
c5e096 | 1999-10-04 | Per Hedbor | | return 0;
}
if( !port )
port = prot->default_port;
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | urls[ url ] = ([ "conf":conf, "path":path, "hostname": host ]);
urls[ ourl ] = urls[url] + ([]);
sorted_urls += ({ url });
array(string)|int(-1..0) required_hosts;
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | |
|
8fb517 | 2000-05-27 | Per Hedbor | | if (is_ip(host))
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | required_hosts = ({ host });
|
5ee285 | 2004-01-14 | Henrik Grubbström (Grubba) | | else if(!sizeof(required_hosts =
filter(replace(opts->ip||"", " ","")/",", is_ip)) )
|
8fb517 | 2000-05-27 | Per Hedbor | | required_hosts = find_ips_for( host );
|
b6fb05 | 1999-11-02 | Per Hedbor | |
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | if (!required_hosts) {
report_error(LOC_M(23, "Cannot register URL %s!")+"\n", url);
return 0;
}
|
c5e096 | 1999-10-04 | Per Hedbor | |
mapping m;
if( !( m = open_ports[ protocol ] ) )
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | |
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
c86a47 | 2005-11-14 | Martin Stjernholm | | m = open_ports[ protocol ] = ([ 0:([]), "::":([]) ]);
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | | if (prot->supports_ipless ) {
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | |
array(string) ipv6 = filter(required_hosts - ({ 0 }), has_value, ":");
array(string) ipv4 = required_hosts - ipv6;
if (m[0][port] && sizeof(ipv4 - ({ 0 }))) {
ipv4 = ({ 0 });
}
|
c86a47 | 2005-11-14 | Martin Stjernholm | | #if constant(__ROXEN_SUPPORTS_IPV6__)
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | | if (m["::"][port] && sizeof(ipv6 - ({ "::" }))) {
ipv6 = ({ "::" });
}
required_hosts = ipv4 + ipv6;
|
0c1282 | 2005-03-10 | Henrik Grubbström (Grubba) | | #else
if (sizeof(ipv6)) {
foreach(ipv6, string p) {
|
359cc0 | 2005-09-30 | Anders Johansson | | report_warning(LOC_M(65, "IPv6 port for URL %s disabled: %s\n"),
|
0c1282 | 2005-03-10 | Henrik Grubbström (Grubba) | | url, p);
}
}
required_hosts = ipv4;
#endif /* __ROXEN_SUPPORTS_IPV6__ */
|
935e1b | 2005-02-23 | Henrik Grubbström (Grubba) | | }
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | int failures;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
38c507 | 2000-02-28 | Per Hedbor | | foreach(required_hosts, string required_host)
{
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | if( m[ required_host ] && m[ required_host ][ port ] )
{
|
7c708f | 2000-02-05 | Henrik Grubbström (Grubba) | | m[required_host][port]->ref(url, urls[url]);
|
38c507 | 2000-02-28 | Per Hedbor | |
|
7c708f | 2000-02-05 | Henrik Grubbström (Grubba) | | urls[url]->port = m[required_host][port];
|
65d200 | 2000-09-25 | Per Hedbor | | urls[ourl]->port = m[required_host][port];
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | continue;
}
if( !m[ required_host ] )
m[ required_host ] = ([ ]);
|
7c708f | 2000-02-05 | Henrik Grubbström (Grubba) | | mixed err;
if (err = catch {
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | m[ required_host ][ port ] = prot( port, required_host );
}) {
|
7c708f | 2000-02-05 | Henrik Grubbström (Grubba) | | failures++;
|
eecdf1 | 2005-02-23 | Henrik Grubbström (Grubba) | | if (has_prefix(describe_error(err), "Invalid address") &&
required_host && has_value(required_host, ":")) {
|
8c4622 | 2005-02-23 | Henrik Grubbström (Grubba) | | report_error(sprintf("Failed to initialize IPv6 port for URL %s"
" (ip %s). Not supported?\n",
|
eecdf1 | 2005-02-23 | Henrik Grubbström (Grubba) | | url, required_host));
} else {
report_error(sprintf("Initializing the port handler for URL %s"
|
8c4622 | 2005-02-23 | Henrik Grubbström (Grubba) | | " failed! (ip %s)\n"
|
eecdf1 | 2005-02-23 | Henrik Grubbström (Grubba) | | "%s\n",
url,
required_host||"ANY",
describe_backtrace(err)));
}
|
7c708f | 2000-02-05 | Henrik Grubbström (Grubba) | | continue;
}
|
abc59a | 2000-08-23 | Per Hedbor | |
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | if( !( m[ required_host ][ port ] ) )
{
m_delete( m[ required_host ], port );
failures++;
if (required_host) {
|
2839e2 | 2001-10-19 | Henrik Grubbström (Grubba) | | report_warning(LOC_M(22, "Binding the port on IP %s failed\n"
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | " for URL %s!\n"),
|
2839e2 | 2001-10-19 | Henrik Grubbström (Grubba) | | required_host, url);
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | }
continue;
}
|
abc59a | 2000-08-23 | Per Hedbor | |
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | urls[ url ]->port = m[ required_host ][ port ];
|
03aa49 | 2000-08-23 | Per Hedbor | | urls[ ourl ]->port = m[ required_host ][ port ];
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | m[ required_host ][ port ]->ref(url, urls[url]);
|
03aa49 | 2000-08-23 | Per Hedbor | |
if( !m[ required_host ][ port ]->bound )
failures++;
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | }
|
abc59a | 2000-08-23 | Per Hedbor | | if (failures == sizeof(required_hosts))
{
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(23, "Cannot register URL %s!")+"\n", url);
|
c5e096 | 1999-10-04 | Per Hedbor | | return 0;
}
sort_urls();
|
851483 | 2000-11-27 | Per Hedbor | | report_notice(" "+LOC_S(3, "Registered %s for %s")+"\n",
|
434bac | 2000-07-14 | Andreas Lange | | url, conf->query_name() );
|
c5e096 | 1999-10-04 | Per Hedbor | | return 1;
}
|
d09399 | 2000-09-25 | Per Hedbor | | Configuration find_configuration( string name )
|
45dc02 | 2000-08-16 | Martin Stjernholm | |
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
b61348 | 2001-01-31 | Per Hedbor | |
if( Configuration o = get_configuration( name ) )
return o;
|
9699bf | 1999-10-11 | Per Hedbor | | name = replace( lower_case( replace(name,"-"," ") )-" ", "/", "-" );
|
d09399 | 2000-09-25 | Per Hedbor | | foreach( configurations, Configuration o )
|
9699bf | 1999-10-11 | Per Hedbor | | {
|
066674 | 1999-12-07 | Henrik Grubbström (Grubba) | | if( (lower_case( replace( replace(o->name, "-"," ") - " " ,
"/", "-" ) ) == name) ||
(lower_case( replace( replace(o->query_name(), "-", " ") - " " ,
"/", "-" ) ) == name) )
|
c5e096 | 1999-10-04 | Per Hedbor | | return o;
|
9699bf | 1999-10-11 | Per Hedbor | | }
|
066674 | 1999-12-07 | Henrik Grubbström (Grubba) | | return 0;
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | static int last_hrtime = gethrtime(1)/100;
|
1c66df | 2004-05-03 | Henrik Grubbström (Grubba) | | static int clock_sequence = random(0x4000);
|
0cae03 | 2004-05-03 | Henrik Grubbström (Grubba) | | static string hex_mac_address =
Crypto.string_to_hex(Crypto.randomness.reasonably_random()->read(6)|
|
b3117f | 2004-05-04 | Henrik Grubbström (Grubba) | | "\1\0\0\0\0\0");
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | |
string new_uuid_string()
{
int now = gethrtime(1)/100;
if (now != last_hrtime) {
|
1c66df | 2004-05-03 | Henrik Grubbström (Grubba) | | clock_sequence = random(0x4000);
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | last_hrtime = now;
}
|
1c66df | 2004-05-03 | Henrik Grubbström (Grubba) | | int seq = clock_sequence++;
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | #if 0
now -= Calendar.parse("%Y-%M-%D %h:%m:%s.%f %z",
"1582-10-15 00:00:00.00 GMT")->unix_time() * 10000000;
#else /* !0 */
|
1c66df | 2004-05-03 | Henrik Grubbström (Grubba) | | now += 0x01b21dd213814000;
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | #endif /* 0 */
now &= 0x0fffffffffffffff;
now |= 0x1000000000000000;
clock_sequence &= 0x3fff;
|
ce6a73 | 2004-05-03 | Henrik Grubbström (Grubba) | | clock_sequence |= 0x8000;
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | return sprintf("%08x-%04x-%04x-%04x-%s",
now & 0xffffffff,
(now >> 32) & 0xffff,
(now >> 48) & 0xffff,
clock_sequence,
|
0cae03 | 2004-05-03 | Henrik Grubbström (Grubba) | | hex_mac_address);
|
27047d | 2004-05-03 | Henrik Grubbström (Grubba) | | }
|
c5e096 | 1999-10-04 | Per Hedbor | | mapping(string:array(int)) error_log=([]);
|
ec2fe1 | 1997-06-09 | Henrik Grubbström (Grubba) | |
|
a6ef1f | 2000-03-28 | Johan Sundström | |
|
c60cae | 2000-02-02 | Johan Sundström | | void nwrite(string s, int|void perr, int|void errtype,
|
c821c3 | 1999-12-27 | Martin Stjernholm | | object|void mod, object|void conf)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
add34e | 2000-08-17 | Per Hedbor | | int log_time = time(1);
|
0fe69d | 2000-03-19 | Martin Nilsson | | string reference = (mod ? Roxen.get_modname(mod) : conf && conf->name) || "";
|
c60cae | 2000-02-02 | Johan Sundström | | string log_index = sprintf("%d,%s,%s", errtype, reference, s);
if(!error_log[log_index])
error_log[log_index] = ({ log_time });
|
c5e096 | 1999-10-04 | Per Hedbor | | else
|
c60cae | 2000-02-02 | Johan Sundström | | error_log[log_index] += ({ log_time });
|
e99fd4 | 1999-11-17 | Per Hedbor | |
if( mod )
{
|
040f88 | 2001-08-20 | Per Hedbor | | if( mod->error_log )
mod->error_log[log_index] += ({ log_time });
|
e99fd4 | 1999-11-17 | Per Hedbor | | }
if( conf )
{
|
040f88 | 2001-08-20 | Per Hedbor | | if( conf->error_log )
conf->error_log[log_index] += ({ log_time });
|
e99fd4 | 1999-11-17 | Per Hedbor | | }
|
c60cae | 2000-02-02 | Johan Sundström | | if(errtype >= 1)
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug( s );
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
2ff846 | 1999-09-02 | Per Hedbor | | int boot_time =time();
int start_time =time();
|
b1fca0 | 1996-11-12 | Per Hedbor | |
string version()
{
|
10089c | 2000-05-17 | Martin Nilsson | | #ifndef NSERIOUS
|
8552d9 | 2001-01-13 | Martin Nilsson | | return query("default_ident")?real_version:query("ident");
|
daff90 | 2000-02-23 | Martin Nilsson | | #else
multiset choices=(<>);
|
8552d9 | 2001-01-13 | Martin Nilsson | | string version=query("default_ident")?real_version:query("ident");
|
089364 | 2000-02-25 | Martin Nilsson | | return version+", "+ ({
"Applier of Templates",
"Beautifier of Layouts",
"Conqueror of Comdex",
"Deliverer of Documents",
"Enhancer of Abilities",
"Freer of Webmasters",
"Generator of Logs",
"Helper of Users",
"Interpreter of Scripts",
"Juggler of Java-code",
"Keeper of Databases",
"Locator of Keywords",
"Manipulator of Data",
"Negatiator of Protocols",
"Operator of Sites",
"Provider of Contents",
"Quintessence of Quality",
"Responder to Connections",
"Server of Webs",
"Translator of Texts",
"Unifier of Interfaces",
"Valet of Visitors",
"Watcher for Requests",
"Xylem of Services",
"Yielder of Information",
"Zenith of Extensibility"
})[random(26)];
|
daff90 | 2000-02-23 | Martin Nilsson | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | | public void log(mapping file, RequestID request_id)
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
81f8af | 1999-12-20 | Martin Nilsson | | if(!request_id->conf) return;
|
14179b | 1997-01-29 | Per Hedbor | | request_id->conf->log(file, request_id);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
|
3e3bab | 2001-01-19 | Per Hedbor | | #if ROXEN_COMPAT < 2.2
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
3e3bab | 2001-01-19 | Per Hedbor | | private Stdio.File current_user_id_file;
|
b1fca0 | 1996-11-12 | Per Hedbor | | private int current_user_id_number, current_user_id_file_last_mod;
private void restore_current_user_id_number()
{
if(!current_user_id_file)
current_user_id_file = open(configuration_dir + "LASTUSER~", "rwc");
if(!current_user_id_file)
{
call_out(restore_current_user_id_number, 2);
return;
|
81f8af | 1999-12-20 | Martin Nilsson | | }
|
b1fca0 | 1996-11-12 | Per Hedbor | | current_user_id_number = (int)current_user_id_file->read(100);
current_user_id_file_last_mod = current_user_id_file->stat()[2];
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Restoring unique user ID information. (" + current_user_id_number
+ ")\n");
|
323569 | 1998-03-26 | Per Hedbor | | #ifdef FD_DEBUG
|
434bac | 2000-07-14 | Andreas Lange | | mark_fd(current_user_id_file->query_fd(), "Unique user ID logfile.\n");
|
323569 | 1998-03-26 | Per Hedbor | | #endif
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
int increase_id()
{
if(!current_user_id_file)
{
restore_current_user_id_number();
|
add34e | 2000-08-17 | Per Hedbor | | return current_user_id_number+time(1);
|
b1fca0 | 1996-11-12 | Per Hedbor | | }
if(current_user_id_file->stat()[2] != current_user_id_file_last_mod)
restore_current_user_id_number();
current_user_id_number++;
current_user_id_file->seek(0);
current_user_id_file->write((string)current_user_id_number);
current_user_id_file_last_mod = current_user_id_file->stat()[2];
return current_user_id_number;
}
|
1138fd | 2001-05-29 | Martin Nilsson | | #endif // ROXEN_COMPAT < 2.2
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
38b81e | 2001-01-06 | Martin Nilsson | | private int unique_id_counter;
string create_unique_id()
{
object md5 = Crypto.md5();
|
0569fa | 2001-09-29 | Martin Nilsson | | md5->update(query("server_salt") + start_time + "|" +
(unique_id_counter++) + "|" + time(1));
|
38b81e | 2001-01-06 | Martin Nilsson | | return Crypto.string_to_hex(md5->digest());
}
|
c8ee71 | 2000-09-09 | Andreas Lange | |
|
dbfe9d | 2000-04-13 | Per Hedbor | | #ifndef __NT__
|
ee8b20 | 1998-07-13 | David Hedbor | | static int abs_started;
|
6ca8f6 | 1998-10-13 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | void restart_if_stuck (int force)
|
622e7a | 2001-12-04 | Martin Stjernholm | |
|
6ca8f6 | 1998-10-13 | Per Hedbor | | {
|
ee8b20 | 1998-07-13 | David Hedbor | | remove_call_out(restart_if_stuck);
|
8552d9 | 2001-01-13 | Martin Nilsson | | if (!(query("abs_engage") || force))
|
edc9af | 1998-07-11 | David Hedbor | | return;
|
81f8af | 1999-12-20 | Martin Nilsson | | if(!abs_started)
|
6ca8f6 | 1998-10-13 | Per Hedbor | | {
|
ee8b20 | 1998-07-13 | David Hedbor | | abs_started = 1;
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("Anti-Block System Enabled.\n");
|
ee8b20 | 1998-07-13 | David Hedbor | | }
call_out (restart_if_stuck,10);
|
e0e50e | 2001-11-23 | Anders Johansson | |
|
6ca8f6 | 1998-10-13 | Per Hedbor | | signal(signum("SIGALRM"),
lambda( int n ) {
|
0bbe65 | 2001-11-22 | Henrik Grubbström (Grubba) | | if (!query("abs_engage")) {
abs_started = 0;
report_debug("Anti-Block System Disabled.\n");
return;
}
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("**** %s: ABS engaged!\n"
|
15f277 | 2003-12-04 | Anders Johansson | | "Waited more than %d minute(s).\n"
|
81f8af | 1999-12-20 | Martin Nilsson | | "Trying to dump backlog: \n",
|
15f277 | 2003-12-04 | Anders Johansson | | ctime(time()) - "\n",
query("abs_timeout"));
|
b0659e | 1999-07-20 | Henrik Grubbström (Grubba) | | catch {
describe_all_threads();
};
|
81f8af | 1999-12-20 | Martin Nilsson | | report_debug("**** %s: ABS exiting roxen!\n\n",
ctime(time()));
|
6ca8f6 | 1998-10-13 | Per Hedbor | | _exit(1);
});
|
e0e50e | 2001-11-23 | Anders Johansson | | int t = alarm (60*query("abs_timeout")+20);
|
edc9af | 1998-07-11 | David Hedbor | | }
|
dbfe9d | 2000-04-13 | Per Hedbor | | #endif
|
edc9af | 1998-07-11 | David Hedbor | |
|
4ed099 | 2003-01-15 | Henrik Grubbström (Grubba) | | function(string:Sql.Sql) dbm_cached_get;
|
753a83 | 1999-08-30 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | class ImageCache
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
0b4177 | 2001-09-06 | Per Hedbor | | #define QUERY(X,Y...) get_db()->query(X,Y)
|
2ff846 | 1999-09-02 | Per Hedbor | | string name;
string dir;
function draw_function;
|
e7ac49 | 2003-04-06 | Anders Johansson | | mapping(string:array(mapping|int)) meta_cache = ([]);
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | |
|
23b7ec | 2001-08-27 | Per Hedbor | | string documentation(void|string tag_n_args)
{
|
29fac1 | 2001-01-04 | Martin Nilsson | | string doc = Stdio.read_file("base_server/image_cache.xml");
if(!doc) return "";
|
6f76f1 | 2000-06-01 | Martin Nilsson | | if(!tag_n_args)
|
4a45f1 | 2001-03-13 | Martin Nilsson | | return Parser.HTML()->add_container("ex", "")->
add_quote_tag("!--","","--")->finish(doc)->read();
|
6f76f1 | 2000-06-01 | Martin Nilsson | | return replace(doc, "###", tag_n_args);
}
|
34d3fa | 1999-04-22 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | static mapping meta_cache_insert( string i, mapping what )
{
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("MD insert for %O: %O\n", i, what );
#endif
if( sizeof( meta_cache ) > 1000 )
|
e7ac49 | 2003-04-06 | Anders Johansson | | sync_meta();
if( what ) {
meta_cache[i] = ({ what, 0 });
return what;
}
|
4afcd4 | 2001-08-09 | Per Hedbor | | else
m_delete( meta_cache, i );
return 0;
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
2ff846 | 1999-09-02 | Per Hedbor | | static mixed frommapp( mapping what )
|
753a83 | 1999-08-30 | Per Hedbor | | {
|
482ac3 | 2001-03-16 | Per Hedbor | | if( !what )
error( "Got invalid argcache-entry\n" );
|
ede135 | 2000-08-12 | Martin Stjernholm | | if( !zero_type(what[""]) ) return what[""];
|
2ff846 | 1999-09-02 | Per Hedbor | | return what;
|
753a83 | 1999-08-30 | Per Hedbor | | }
|
6a613a | 2002-06-17 | Anders Johansson | | static void|mapping draw( string name, RequestID id )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("draw %O\n", name );
#endif
|
4afcd4 | 2001-08-09 | Per Hedbor | | mixed args = Array.map( Array.map( name/"$", argcache->lookup,
|
482ac3 | 2001-03-16 | Per Hedbor | | id->client ), frommapp);
|
aea165 | 2001-06-26 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | mapping meta;
string data;
|
6f0396 | 2001-02-09 | Per Hedbor | | array guides;
|
2ff846 | 1999-09-02 | Per Hedbor | | mixed reply = draw_function( @copy_value(args), id );
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
e96b50 | 2004-06-11 | Henrik Grubbström (Grubba) | | if( !reply ) {
#ifdef ARG_CACHE_DEBUG
werror("%O(%{%O, %}%O) ==> 0\n",
draw_function, args, id);
#endif
|
aea165 | 2001-06-26 | Per Hedbor | | return;
|
e96b50 | 2004-06-11 | Henrik Grubbström (Grubba) | | }
|
aea165 | 2001-06-26 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | if( arrayp( args ) )
args = args[0];
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
37ecea | 2000-02-21 | Per Hedbor | | if( arrayp( reply ) )
|
6f0396 | 2001-02-09 | Per Hedbor | | {
guides = reply->get_misc_value( "image_guides" )-({});
if( sizeof( guides ) )
guides = guides[0];
|
37ecea | 2000-02-21 | Per Hedbor | | reply = Image.lay( reply );
|
6f0396 | 2001-02-09 | Per Hedbor | | }
|
37ecea | 2000-02-21 | Per Hedbor | | if( objectp( reply ) && reply->image )
{
|
6f0396 | 2001-02-09 | Per Hedbor | | if( !guides )
guides = reply->get_misc_value( "image_guides" );
|
37ecea | 2000-02-21 | Per Hedbor | | reply = ([
"img":reply->image(),
"alpha":reply->alpha(),
]);
}
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | if( objectp( reply ) || (mappingp(reply) && reply->img) )
|
b1fca0 | 1996-11-12 | Per Hedbor | | {
|
2ff846 | 1999-09-02 | Per Hedbor | | int quant = (int)args->quant;
string format = lower_case(args->format || "gif");
string dither = args->dither;
Image.Colortable ct;
|
e9d7c5 | 1999-11-02 | Per Hedbor | | Image.Color.Color bgcolor;
|
3e3bab | 2001-01-19 | Per Hedbor | | Image.Image alpha;
|
81f8af | 1999-12-20 | Martin Nilsson | | int true_alpha;
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | if( args->fs || dither == "fs" )
dither = "floyd_steinberg";
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
6f0396 | 2001-02-09 | Per Hedbor | | if( dither == "random" )
|
2ff846 | 1999-09-02 | Per Hedbor | | dither = "random_dither";
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
81f8af | 1999-12-20 | Martin Nilsson | | if( format == "jpg" )
|
2ff846 | 1999-09-02 | Per Hedbor | | format = "jpeg";
|
b1fca0 | 1996-11-12 | Per Hedbor | |
|
112b1c | 2000-02-02 | Per Hedbor | | if( dither )
dither = replace( dither, "-", "_" );
|
2ff846 | 1999-09-02 | Per Hedbor | | if(mappingp(reply))
{
alpha = reply->alpha;
reply = reply->img;
|
93ebdd | 1999-03-11 | Martin Stjernholm | | }
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
c3a53d | 1999-06-25 | Per Hedbor | | if( args["true-alpha"] )
true_alpha = 1;
|
e7e603 | 1999-11-05 | Per Hedbor | | if( args["background"] || args["background-color"])
|
6f0396 | 2001-02-09 | Per Hedbor | | bgcolor = Image.Color( args["background"]||args["background-color"] );
|
e9d7c5 | 1999-11-02 | Per Hedbor | |
|
b79be2 | 1999-06-11 | Per Hedbor | | if( args["opaque-value"] )
{
|
6f0396 | 2001-02-09 | Per Hedbor | | if( !bgcolor )
true_alpha = 1;
|
b79be2 | 1999-06-11 | Per Hedbor | | int ov = (int)(((float)args["opaque-value"])*2.55);
if( ov < 0 )
ov = 0;
else if( ov > 255 )
ov = 255;
if( alpha )
|
356484 | 2000-09-15 | Per Hedbor | | alpha *= ov;
|
b79be2 | 1999-06-11 | Per Hedbor | | else
|
2537c3 | 2000-02-14 | Per Hedbor | | alpha = Image.Image( reply->xsize(), reply->ysize(), ov,ov,ov );
|
b79be2 | 1999-06-11 | Per Hedbor | | }
|
c52692 | 1999-05-18 | Per Hedbor | |
|
91a156 | 2000-04-11 | Per Hedbor | | if( args->gamma )
reply = reply->gamma( (float)args->gamma );
if( bgcolor && alpha && !true_alpha )
{
reply = Image.Image( reply->xsize(),
reply->ysize(), bgcolor )
->paste_mask( reply, alpha );
alpha = alpha->threshold( 4 );
}
|
6f0396 | 2001-02-09 | Per Hedbor | | int x0, y0, x1=reply->xsize(), y1=reply->ysize(), xc, yc;
|
3cbd0d | 2000-01-31 | Per Hedbor | | if( args["x-offset"] || args["xoffset"] )
x0 = (int)(args["x-offset"]||args["xoffset"]);
if( args["y-offset"] || args["yoffset"] )
y0 = (int)(args["y-offset"]||args["yoffset"]);
|
6f0396 | 2001-02-09 | Per Hedbor | | if( args["width"] || args["x-size"] )
x1 = (int)(args["x-size"]||args["width"]);
if( args["height"] || args["y-size"] )
y1 = (int)(args["y-size"]||args["height"]);
|
3cbd0d | 2000-01-31 | Per Hedbor | |
|
6f0396 | 2001-02-09 | Per Hedbor | | array xguides, yguides;
|
83f54a | 2003-01-16 | Martin Stjernholm | | function sort_guides = lambda()
|
6f0396 | 2001-02-09 | Per Hedbor | | {
xguides = ({}); yguides = ({});
if( guides )
{
foreach( guides, object g )
if( g->pos > 0 )
if( g->vertical )
{
if( g->pos < reply->xsize() )
xguides += ({ g->pos });
}
else
if( g->pos < reply->ysize() )
yguides += ({ g->pos });
sort( xguides ); sort( yguides );
}
};
|
3cbd0d | 2000-01-31 | Per Hedbor | | if( args->crop )
{
|
6f0396 | 2001-02-09 | Per Hedbor | | int gx=1, gy=1, gx2, gy2;
if( sscanf( args["guides-index"]||"", "%d,%d", gx, gy ) == 2 )
{
gx2 = gx+1;
gy2 = gy+1;
sscanf( args["guides-index"]||"", "%d,%d-%d,%d", gx, gy, gx2, gy2 );
}
switch( args->crop )
{
case "guides-cross":
sort_guides();
if( sizeof(xguides) && sizeof(yguides) )
{
xc = xguides[ min(sizeof(xguides),gx) - 1 ];
yc = yguides[ min(sizeof(yguides),gy) - 1 ];
break;
}
guides=0;
case "guides-region":
sort_guides();
if( (sizeof(xguides)>1) && (sizeof(yguides)>1) )
{
gx = min(sizeof(xguides)-1,gx) - 1;
gy = min(sizeof(yguides)-1,gy) - 1;
gx2 = min(sizeof(xguides),gx2) - 1;
gy2 = min(sizeof(yguides),gy2) - 1;
x0 = xguides[gx]; x1 = xguides[gx2] - x0;
y0 = yguides[gy]; y1 = yguides[gy2] - y0;
break;
}
default:
if( sscanf( args->crop, "%d,%d-%d,%d", x0, y0, x1, y1 ) == 4)
{
x1 -= x0;
y1 -= y0;
}
|
b0e2f8 | 2001-11-28 | Anders Johansson | | break;
|
6f0396 | 2001-02-09 | Per Hedbor | | case "auto":
[ x0, y0, x1, y1 ] = reply->find_autocrop();
|
de130c | 2004-01-21 | Jonas Wallden | | x1 = x1 - x0 + 1;
y1 = y1 - y0 + 1;
|
6f0396 | 2001-02-09 | Per Hedbor | | }
|
3cbd0d | 2000-01-31 | Per Hedbor | | }
|
83f54a | 2003-01-16 | Martin Stjernholm | | sort_guides = 0;
|
3cbd0d | 2000-01-31 | Per Hedbor | |
|
6f0396 | 2001-02-09 | Per Hedbor | | #define SCALEI 1
#define SCALEF 2
|
482ac3 | 2001-03-16 | Per Hedbor | | #define SCALEA 4
#define CROP 8
|
6f0396 | 2001-02-09 | Per Hedbor | |
|
83f54a | 2003-01-16 | Martin Stjernholm | | function do_scale_and_crop = lambda ( int x0, int y0,
int x1, int y1,
int|float w, int|float h,
int type )
|
3cbd0d | 2000-01-31 | Per Hedbor | | {
|
6f0396 | 2001-02-09 | Per Hedbor | | if( (type & CROP) && x1 && y1
&& ((x1 != reply->xsize()) || (y1 != reply->ysize())
|| x0 || y0 ) )
{
reply = reply->copy( x0, y0, x0+x1-1, y0+y1-1,
(bgcolor?bgcolor->rgb():0) );
if( alpha )
alpha = alpha->copy( x0, y0, x0+x1-1,y0+y1-1, Image.Color.black);
}
|
3cbd0d | 2000-01-31 | Per Hedbor | |
|
6f0396 | 2001-02-09 | Per Hedbor | | if( type & SCALEI )
{
if( xc || yc )
{
if( h && !w )
w = (reply->xsize() * h) / reply->ysize();
if( w && !h )
h = (reply->ysize() * w) / reply->xsize();
x0 = max( xc - w/2, 0 );
y0 = max( yc - h/2, 0 );
x1 = w; y1 = h;
if( x0 + x1 > reply->xsize() )
{
x0 = reply->xsize()-w;
if( x0 < 0 )
{
x0 = 0;
x1 = reply->xsize();
}
}
if( y0 + y1 > reply->ysize() )
{
y0 = reply->ysize()-h;
if( y0 < 0 )
{
y0 = 0;
y1 = reply->ysize();
}
}
reply = reply->copy( x0, y0, x0+x1-1, y0+y1-1,
(bgcolor?bgcolor->rgb():0) );
if( alpha )
alpha = alpha->copy( x0, y0, x0+x1-1,y0+y1-1, Image.Color.black);
}
}
|
482ac3 | 2001-03-16 | Per Hedbor | | if( (type & SCALEF) && (w != 1.0) )
|
6f0396 | 2001-02-09 | Per Hedbor | | {
reply = reply->scale( w );
if( alpha )
alpha = alpha->scale( w );
}
|
482ac3 | 2001-03-16 | Per Hedbor | | else if( (type & SCALEA) &&
((reply->xsize() != w) || (reply->ysize() != h)) )
|
6f0396 | 2001-02-09 | Per Hedbor | | {
|
482ac3 | 2001-03-16 | Per Hedbor | | reply = reply->scale( w,h );
if( alpha )
alpha = alpha->scale( w,h );
}
else if( (type & SCALEI) &&
((reply->xsize() != w) || (reply->ysize() != h)) )
{
|
d228c7 | 2001-03-17 | Per Hedbor | | if( w && h )
{
|
f78ca4 | 2004-03-09 | Stephen R. van den Berg | | if( (w * (float)reply->ysize()) < (h * (float)reply->xsize()) )
|
d228c7 | 2001-03-17 | Per Hedbor | | h = 0;
else
w = 0;
}
|
e0dda0 | 2001-04-17 | Per Hedbor | | w = min( w, reply->xsize() );
h = min( h, reply->ysize() );
|
6f0396 | 2001-02-09 | Per Hedbor | | reply = reply->scale( w,h );
if( alpha )
alpha = alpha->scale( w,h );
}
};
|
fa91d9 | 2005-01-17 | Jonas Wallden | | if( sizeof((string) (args->scale || "")) )
|
c52692 | 1999-05-18 | Per Hedbor | | {
int x, y;
if( sscanf( args->scale, "%d,%d", x, y ) == 2)
|
482ac3 | 2001-03-16 | Per Hedbor | | do_scale_and_crop( x0, y0, x1, y1, x, y, SCALEA|CROP );
|
3255b1 | 1999-05-19 | Per Hedbor | | else if( (float)args->scale < 3.0)
|
6f0396 | 2001-02-09 | Per Hedbor | | do_scale_and_crop( x0, y0, x1, y1,
((float)args->scale), ((float)args->scale),
SCALEF|CROP );
|
c52692 | 1999-05-18 | Per Hedbor | | }
|
6f0396 | 2001-02-09 | Per Hedbor | | else
|
fa91d9 | 2005-01-17 | Jonas Wallden | | if( sizeof( (string) (args->maxwidth || args->maxheight ||
args["max-width"] || args["max-height"] || "")) )
|
c52692 | 1999-05-18 | Per Hedbor | | {
|
6f0396 | 2001-02-09 | Per Hedbor | | int x = (int)args->maxwidth|| (int)args["max-width"];
|
e7e603 | 1999-11-05 | Per Hedbor | | int y = (int)args->maxheight||(int)args["max-height"];
|
6f0396 | 2001-02-09 | Per Hedbor | | do_scale_and_crop( x0, y0, x1, y1, x, y, SCALEI|CROP );
|
c52692 | 1999-05-18 | Per Hedbor | | }
|
6f0396 | 2001-02-09 | Per Hedbor | | else
do_scale_and_crop( x0, y0, x1, y1, 0, 0, CROP );
|
83f54a | 2003-01-16 | Martin Stjernholm | | do_scale_and_crop = 0;
|
c52692 | 1999-05-18 | Per Hedbor | |
|
6f0396 | 2001-02-09 | Per Hedbor | | if( args["span-width"] || args["span-height"] )
|
d59370 | 2001-01-23 | Anders Johansson | | {
int width = (int)args["span-width"];
int height = (int)args["span-height"];
|
6f0396 | 2001-02-09 | Per Hedbor | |
|
d59370 | 2001-01-23 | Anders Johansson | | if( (width && reply->xsize() > width) ||
(height && reply->ysize() > height) )
{
if( (width && height && (reply->xsize() / (float)width >
reply->ysize() / (float)height)) ||
!height )
{
reply = reply->scale( width, 0 );
if( alpha )
alpha = alpha->scale( width, 0 );
}
else if( height )
{
reply = reply->scale( 0, height );
if( alpha )
alpha = alpha->scale( 0, height );
}
}
int x1,x2,y1,y2;
if( width )
{
x1 = -((width - reply->xsize()) / 2);
x2 = x1 + width - 1;
}
if( height )
{
y1 = -((height - reply->ysize()) / 2);
y2 = y1 + height - 1;
}
if( width && height )
{
reply = reply->copy(x1,y1,x2,y2,(bgcolor?bgcolor->rgb():0));
if( alpha ) alpha = alpha->copy(x1,y1,x2,y2);
}
else if( width )
{
reply = reply->copy(x1,0,x2,reply->ysize(),(bgcolor?bgcolor->rgb():0));
if ( alpha ) alpha = alpha->copy(x1,0,x2,alpha->ysize());
}
else
{
reply = reply->copy(0,y1,reply->xsize(),y2,(bgcolor?bgcolor->rgb():0));
if( alpha ) alpha = alpha->copy(0,y1,alpha->xsize(),y2);
}
}
|
112b1c | 2000-02-02 | Per Hedbor | | if( args["rotate-cw"] || args["rotate-ccw"])
{
float degree = (float)(args["rotate-cw"] || args["rotate-ccw"]);
|
66868a | 2000-04-15 | Per Hedbor | | switch( args["rotate-unit"] && args["rotate-unit"][0..0] )
|
112b1c | 2000-02-02 | Per Hedbor | | {
|
9792c7 | 2000-05-16 | Henrik Grubbström (Grubba) | | case "r": degree = (degree / (2*3.1415)) * 360; break;
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | case "d": break;
|
66868a | 2000-04-15 | Per Hedbor | | case "n": degree = (degree / 400) * 360; break;
case "p": degree = (degree / 1.0) * 360; break;
|
112b1c | 2000-02-02 | Per Hedbor | | }
|
66868a | 2000-04-15 | Per Hedbor | | if( args["rotate-cw"] )
|
112b1c | 2000-02-02 | Per Hedbor | | degree = -degree;
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | if(!alpha)
|
66868a | 2000-04-15 | Per Hedbor | | alpha = reply->copy()->clear(255,255,255);
reply = reply->rotate_expand( degree );
|
f52669 | 2000-05-16 | Henrik Grubbström (Grubba) | | alpha = alpha->rotate( degree, 0,0,0 );
|
112b1c | 2000-02-02 | Per Hedbor | | }
if( args["mirror-x"] )
{
if( alpha )
alpha = alpha->mirrorx();
reply = reply->mirrorx();
}
if( args["mirror-y"] )
{
if( alpha )
alpha = alpha->mirrory();
reply = reply->mirrory();
}
|
91a156 | 2000-04-11 | Per Hedbor | | if( bgcolor && alpha && !true_alpha )
|
e7e603 | 1999-11-05 | Per Hedbor | | {
reply = Image.Image( reply->xsize(),
reply->ysize(), bgcolor )
->paste_mask( reply, alpha );
}
|
91a156 | 2000-04-11 | Per Hedbor | | if( args["cs-rgb-hsv"] )reply = reply->rgb_to_hsv();
if( args["cs-grey"] ) reply = reply->grey();
if( args["cs-invert"] ) reply = reply->invert();
if( args["cs-hsv-rgb"] )reply = reply->hsv_to_rgb();
if( !true_alpha && alpha )
alpha = alpha->threshold( 4 );
|
69a869 | 1999-05-18 | Per Hedbor | | if( quant || (format=="gif") )
{
|
641a88 | 2000-06-01 | Martin Nilsson | | int ncols = quant;
if( format=="gif" ) {
ncols = ncols||id->misc->defquant||32;
if( ncols > 254 )
ncols = 254;
}
|
000c78 | 1999-05-25 | Per Hedbor | | ct = Image.Colortable( reply, ncols );
|
69a869 | 1999-05-18 | Per Hedbor | | if( dither )
|
23264c | 2000-10-17 | Per Hedbor | | {
if( dither == "random" )
dither = "random_grey";
|
000c78 | 1999-05-25 | Per Hedbor | | if( ct[ dither ] )
ct[ dither ]();
|
69a869 | 1999-05-18 | Per Hedbor | | else
ct->ordered();
|
23264c | 2000-10-17 | Per Hedbor | |
}
|
69a869 | 1999-05-18 | Per Hedbor | | }
mapping enc_args = ([]);
if( ct )
enc_args->colortable = ct;
|
a1c869 | 2000-09-12 | Per Hedbor | |
|
69a869 | 1999-05-18 | Per Hedbor | | if( alpha )
enc_args->alpha = alpha;
|
c52692 | 1999-05-18 | Per Hedbor | | foreach( glob( "*-*", indices(args)), string n )
if(sscanf(n, "%*[^-]-%s", string opt ) == 2)
|
a1c869 | 2000-09-12 | Per Hedbor | | if( opt != "alpha" )
enc_args[opt] = (int)args[n];
|
c52692 | 1999-05-18 | Per Hedbor | |
|
69a869 | 1999-05-18 | Per Hedbor | | switch(format)
{
|
34fc59 | 2001-03-01 | Per Hedbor | | case "wbf":
format = "wbmp";
case "wbmp":
|
387fa6 | 2001-03-05 | Per Hedbor | | Image.Colortable bw=Image.Colortable( ({ ({ 0,0,0 }),
({ 255,255,255 }) }) );
bw->floyd_steinberg();
data = Image.WBF.encode( bw->map( reply ), enc_args );
|
34fc59 | 2001-03-01 | Per Hedbor | | break;
|
69a869 | 1999-05-18 | Per Hedbor | | case "gif":
|
f04b92 | 2000-09-13 | Jonas Wallden | | #if constant(Image.GIF) && constant(Image.GIF.encode)
|
c3a53d | 1999-06-25 | Per Hedbor | | if( alpha && true_alpha )
|
b79be2 | 1999-06-11 | Per Hedbor | | {
|
91a156 | 2000-04-11 | Per Hedbor | | Image.Colortable bw=Image.Colortable( ({ ({ 0,0,0 }),
({ 255,255,255 }) }) );
|
e9d7c5 | 1999-11-02 | Per Hedbor | | bw->floyd_steinberg();
alpha = bw->map( alpha );
|
b79be2 | 1999-06-11 | Per Hedbor | | }
|
000c78 | 1999-05-25 | Per Hedbor | | if( catch {
if( alpha )
data = Image.GIF.encode_trans( reply, ct, alpha );
else
data = Image.GIF.encode( reply, ct );
})
data = Image.GIF.encode( reply );
|
23264c | 2000-10-17 | Per Hedbor | | break;
|
f04b92 | 2000-09-13 | Jonas Wallden | | #else
|
23264c | 2000-10-17 | Per Hedbor | |
format = "png";
|
f04b92 | 2000-09-13 | Jonas Wallden | | #endif
|
e9d7c5 | 1999-11-02 | Per Hedbor | |
|
69a869 | 1999-05-18 | Per Hedbor | | case "png":
|
e9d7c5 | 1999-11-02 | Per Hedbor | | if( ct ) enc_args->palette = ct;
|
69a869 | 1999-05-18 | Per Hedbor | | m_delete( enc_args, "colortable" );
|
36a6ad | 2000-09-15 | Per Hedbor | | if( !(args["png-use-alpha"] || args["true-alpha"]) )
m_delete( enc_args, "alpha" );
else if( enc_args->alpha )
m_delete( enc_args, "palette");
else
|
f04b92 | 2000-09-13 | Jonas Wallden | | m_delete( enc_args, "alpha" );
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
69a869 | 1999-05-18 | Per Hedbor | | default:
|
23264c | 2000-10-17 | Per Hedbor | | if(!Image[upper_case( format )]
|| !Image[upper_case( format )]->encode )
|
34fc59 | 2001-03-01 | Per Hedbor | | error("Image format "+format+" not supported\n");
|
f04b92 | 2000-09-13 | Jonas Wallden | | data = Image[upper_case( format )]->encode( reply, enc_args );
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | | meta =
([
|
69a869 | 1999-05-18 | Per Hedbor | | "xsize":reply->xsize(),
"ysize":reply->ysize(),
|
34fc59 | 2001-03-01 | Per Hedbor | | "type":(format == "wbmp" ? "image/vnd.wap.wbmp" : "image/"+format ),
|
69a869 | 1999-05-18 | Per Hedbor | | ]);
|
c52692 | 1999-05-18 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | | else if( mappingp(reply) )
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
6a613a | 2002-06-17 | Anders Johansson | |
if(reply->error)
return reply;
|
69a869 | 1999-05-18 | Per Hedbor | | meta = reply->meta;
data = reply->data;
if( !meta || !data )
error("Invalid reply mapping.\n"
|
29fac1 | 2001-01-04 | Martin Nilsson | | "Expected ([ \"meta\": ([metadata]), \"data\":\"data\" ])\n"
"Got %O\n", reply);
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("draw %O done\n", name );
#endif
|
31885f | 2001-01-02 | Per Hedbor | |
|
e96b50 | 2004-06-11 | Henrik Grubbström (Grubba) | | mixed err = catch(store_data( name, data, meta ));
#ifdef ARG_CACHE_DEBUG
if (err) {
werror("store_data failed with:\n"
"%s\n", describe_backtrace(err));
}
#endif
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
29fac1 | 2001-01-04 | Martin Nilsson | | static void store_data( string id, string data, mapping meta )
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
55fc49 | 2000-12-30 | Per Hedbor | | if(!stringp(data)) return;
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("store %O (%d bytes)\n", id, strlen(data) );
#endif
|
29fac1 | 2001-01-04 | Martin Nilsson | | meta_cache_insert( id, meta );
string meta_data = encode_value( meta );
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
|
4da2ef | 2003-11-11 | Henrik Grubbström (Grubba) | | werror("Replacing entry for %O\n", id );
|
23b7ec | 2001-08-27 | Per Hedbor | | #endif
|
4da2ef | 2003-11-11 | Henrik Grubbström (Grubba) | | QUERY("REPLACE INTO "+name+
|
2af730 | 2004-02-05 | Anders Johansson | | " (id,size,atime,meta,data) VALUES (%s,%d,UNIX_TIMESTAMP(),%s,%s)",
id, strlen(data)+strlen(meta_data), meta_data, data );
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
aea165 | 2001-06-26 | Per Hedbor | | static mapping restore_meta( string id, RequestID rid )
|
69a869 | 1999-05-18 | Per Hedbor | | {
if( meta_cache[ id ] )
|
e7ac49 | 2003-04-06 | Anders Johansson | | {
meta_cache[ id ][ 1 ] = time(1);
return meta_cache[ id ][ 0 ];
}
|
6e05b2 | 2001-01-01 | Martin Nilsson | |
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
|
678926 | 2001-09-06 | Per Hedbor | | werror("restore meta %O\n", id );
|
23b7ec | 2001-08-27 | Per Hedbor | | #endif
array(mapping(string:string)) q =
QUERY("SELECT meta FROM "+name+" WHERE id=%s", id );
|
4afcd4 | 2001-08-09 | Per Hedbor | |
|
329407 | 2001-09-06 | Per Hedbor | | string s;
if(!sizeof(q) || !strlen(s = q[0]->meta))
|
69a869 | 1999-05-18 | Per Hedbor | | return 0;
|
9fcbed | 2001-01-20 | Per Hedbor | |
|
18e19c | 2000-06-12 | Martin Stjernholm | | mapping m;
|
55fc49 | 2000-12-30 | Per Hedbor | | if (catch (m = decode_value (s)))
{
report_error( "Corrupt data in cache-entry "+id+".\n" );
|
4afcd4 | 2001-08-09 | Per Hedbor | | QUERY( "DELETE FROM "+name+" WHERE id=%s", id);
|
18e19c | 2000-06-12 | Martin Stjernholm | | return 0;
}
|
678926 | 2001-09-06 | Per Hedbor | |
QUERY("UPDATE "+name+" SET atime=UNIX_TIMESTAMP() WHERE id=%s",id );
|
18e19c | 2000-06-12 | Martin Stjernholm | | return meta_cache_insert( id, m );
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
e7ac49 | 2003-04-06 | Anders Johansson | | static void sync_meta()
{
foreach(indices(meta_cache), string id) {
if (meta_cache[id][1])
QUERY("UPDATE "+name+" SET atime=%d WHERE id=%s",
meta_cache[id][1], id);
}
meta_cache = ([]);
}
|
93dd0e | 2000-07-27 | Johan Sundström | | void flush(int|void age)
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
4f2d5f | 2000-03-13 | Per Hedbor | | {
|
354801 | 2001-08-10 | Per Hedbor | | int num;
#ifdef DEBUG
int t = gethrtime();
report_debug("Cleaning "+name+" image cache ... ");
#endif
|
e7ac49 | 2003-04-06 | Anders Johansson | | sync_meta();
|
5c1b62 | 2001-08-01 | Per Hedbor | | uid_cache = ([]);
rst_cache = ([]);
|
55fc49 | 2000-12-30 | Per Hedbor | | if( !age )
{
|
e7ac49 | 2003-04-06 | Anders Johansson | | #ifdef DEBUG
report_debug("cleared\n");
#endif
|
21207e | 2001-06-13 | Per Hedbor | | QUERY( "DELETE FROM "+name );
|
354801 | 2001-08-10 | Per Hedbor | | num = -1;
|
b5e386 | 2000-12-31 | Martin Nilsson | | return;
|
55fc49 | 2000-12-30 | Per Hedbor | | }
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
5c1b62 | 2001-08-01 | Per Hedbor | | array(string) ids =
QUERY( "SELECT id FROM "+name+" WHERE atime < "+age)->id;
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
354801 | 2001-08-10 | Per Hedbor | | num = sizeof( ids );
|
b5e386 | 2000-12-31 | Martin Nilsson | | int q;
while(q<sizeof(ids)) {
|
2c6416 | 2002-12-04 | Marcus Wellhardh | | string list = map(ids[q..q+99], get_db()->quote) * "','";
|
b5e386 | 2000-12-31 | Martin Nilsson | | q+=100;
|
4afcd4 | 2001-08-09 | Per Hedbor | | QUERY( "DELETE FROM "+name+" WHERE id in ('"+list+"')" );
|
55fc49 | 2000-12-30 | Per Hedbor | | }
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
354801 | 2001-08-10 | Per Hedbor | | if( num )
catch
{
QUERY( "OPTIMIZE TABLE "+name );
};
|
29fac1 | 2001-01-04 | Martin Nilsson | |
|
354801 | 2001-08-10 | Per Hedbor | | #ifdef DEBUG
report_debug("%s removed, %dms\n",
|
eae43a | 2001-08-13 | Per Hedbor | | (num==-1?"all":num?(string)num:"none"),
|
354801 | 2001-08-10 | Per Hedbor | | (gethrtime()-t)/1000);
#endif
|
1f58d0 | 2000-01-02 | Martin Nilsson | | }
|
93dd0e | 2000-07-27 | Johan Sundström | | array(int) status(int|void age)
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
93dd0e | 2000-07-27 | Johan Sundström | | {
|
b5e386 | 2000-12-31 | Martin Nilsson | | int imgs=0, size=0, aged=0;
array(mapping(string:string)) q;
|
55fc49 | 2000-12-30 | Per Hedbor | |
|
21207e | 2001-06-13 | Per Hedbor | | q=QUERY("SHOW TABLE STATUS");
|
6e05b2 | 2001-01-01 | Martin Nilsson | | foreach(q, mapping qq)
if(has_prefix(qq->Name, name)) {
imgs = (int)qq->Rows;
size += (int)qq->Data_length;
}
|
b5e386 | 2000-12-31 | Martin Nilsson | |
|
6e05b2 | 2001-01-01 | Martin Nilsson | | if(age) {
|
21207e | 2001-06-13 | Per Hedbor | | q=QUERY("select SUM(1) as num from "+name+" where atime < "+age);
|
6e05b2 | 2001-01-01 | Martin Nilsson | | aged = (int)q[0]->num;
}
|
b5e386 | 2000-12-31 | Martin Nilsson | | return ({ imgs, size, aged });
|
1f58d0 | 2000-01-02 | Martin Nilsson | | }
|
aea165 | 2001-06-26 | Per Hedbor | | static mapping(string:mapping) rst_cache = ([ ]);
static mapping(string:string) uid_cache = ([ ]);
|
4afcd4 | 2001-08-09 | Per Hedbor | |
|
aea165 | 2001-06-26 | Per Hedbor | | static mapping restore( string id, RequestID rid )
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
aea165 | 2001-06-26 | Per Hedbor | | array q;
string uid;
if( zero_type(uid = uid_cache[id]) )
{
|
4afcd4 | 2001-08-09 | Per Hedbor | | q = QUERY( "SELECT uid FROM "+name+" WHERE id=%s",id);
|
aea165 | 2001-06-26 | Per Hedbor | | if( sizeof(q) )
uid = q[0]->uid;
else
uid = 0;
uid_cache[id] = uid;
}
|
90274d | 2001-08-09 | Per Hedbor | | if( uid && strlen(uid) )
|
aea165 | 2001-06-26 | Per Hedbor | | {
User u;
if( !(u=rid->conf->authenticate(rid)) || (u->name() != uid ) )
return rid->conf->authenticate_throw(rid, "User");
}
|
9fcbed | 2001-01-20 | Per Hedbor | | if( rst_cache[ id ] )
return rst_cache[ id ] + ([]);
|
29fac1 | 2001-01-04 | Martin Nilsson | |
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("restore %O\n", id );
#endif
|
23f843 | 2001-09-05 | Per Hedbor | | q = QUERY( "SELECT meta,atime,data FROM "+name+" WHERE id=%s",id);
|
9fcbed | 2001-01-20 | Per Hedbor | | if( sizeof(q) )
|
55fc49 | 2000-12-30 | Per Hedbor | | {
|
4afcd4 | 2001-08-09 | Per Hedbor | | if( sizeof(q[0]->data) )
{
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
4afcd4 | 2001-08-09 | Per Hedbor | | string f = q[0]->data;
|
23b7ec | 2001-08-27 | Per Hedbor | | mapping m;
catch( m = decode_value( q[0]->meta ) );
|
4afcd4 | 2001-08-09 | Per Hedbor | | if( !m ) return 0;
|
9fcbed | 2001-01-20 | Per Hedbor | |
|
4afcd4 | 2001-08-09 | Per Hedbor | | m = Roxen.http_string_answer( f, m->type||("image/gif") );
|
23f843 | 2001-09-05 | Per Hedbor | |
|
4afcd4 | 2001-08-09 | Per Hedbor | | if( strlen( f ) > 6000 )
return m;
rst_cache[ id ] = m;
if( sizeof( rst_cache ) > 100 )
|
41240d | 2001-09-03 | Stefan Wallström | | rst_cache = ([ id : m ]);
|
4afcd4 | 2001-08-09 | Per Hedbor | | return rst_cache[ id ] + ([]);
}
|
23b7ec | 2001-08-27 | Per Hedbor | |
return 0;
|
29fac1 | 2001-01-04 | Martin Nilsson | | }
|
4afcd4 | 2001-08-09 | Per Hedbor | | else
{
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
4afcd4 | 2001-08-09 | Per Hedbor | | User u = rid->conf->authenticate(rid);
string uid = "";
if( u ) uid = u->name();
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
4da2ef | 2003-11-11 | Henrik Grubbström (Grubba) | | QUERY("REPLACE INTO "+name+
" (id,uid,atime) VALUES (%s,%s,UNIX_TIMESTAMP())",
id, uid );
|
4afcd4 | 2001-08-09 | Per Hedbor | | }
return 0;
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
93dd0e | 2000-07-27 | Johan Sundström | | string data( array|string|mapping args, RequestID id, int|void nodraw )
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
23b7ec | 2001-08-27 | Per Hedbor | | mapping res = http_file_answer( args, id, nodraw );
return res && res->data;
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
93dd0e | 2000-07-27 | Johan Sundström | | mapping http_file_answer( array|string|mapping data,
|
81f8af | 1999-12-20 | Martin Nilsson | | RequestID id,
|
c3a53d | 1999-06-25 | Per Hedbor | | int|void nodraw )
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
aea165 | 2001-06-26 | Per Hedbor | |
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
333b54 | 2005-02-25 | Henrik Grubbström (Grubba) | | current_configuration->set(id->conf);
|
69a869 | 1999-05-18 | Per Hedbor | | string na = store( data,id );
mixed res;
|
23b7ec | 2001-08-27 | Per Hedbor | | #ifdef ARG_CACHE_DEBUG
werror("data %O\n", na );
#endif
|
aea165 | 2001-06-26 | Per Hedbor | | if(! (res=restore( na,id )) )
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | mixed err;
if (nodraw || (err = catch {
|
6a613a | 2002-06-17 | Anders Johansson | | if (mapping res = draw( na, id ))
return res;
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | })) {
|
e69667 | 2001-11-13 | Henrik Grubbström (Grubba) | |
|
2354f1 | 2001-12-19 | Marcus Wellhardh | | if(arrayp(err) && sizeof(err) && stringp(err[0]) &&
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | sscanf(err[0], "Requesting unknown key %s\n", string message) == 1)
{
report_debug("Requesting unknown key %s %O from %O\n",
message,
|
2354f1 | 2001-12-19 | Marcus Wellhardh | | id->not_query,
(sizeof(id->referer)?id->referer[0]:"unknown page"));
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | }
|
2354f1 | 2001-12-19 | Marcus Wellhardh | | else
report_debug("Error in draw: %s\n", describe_backtrace(err));
|
e69667 | 2001-11-13 | Henrik Grubbström (Grubba) | | return 0;
}
|
e96b50 | 2004-06-11 | Henrik Grubbström (Grubba) | | if( !(res = restore( na,id )) ) {
error("Draw callback %O did not generate any data.\n"
"na: %O\n"
"id: %O\n",
draw_function, na, id);
}
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
6fd56d | 2001-09-05 | Per Hedbor | | res->stat = ({ 0, 0, 0, 900000000, 0, 0, 0, 0, 0 });
|
000ae2 | 2002-06-13 | Jonas Wallden | |
|
989693 | 2002-10-11 | Jonas Wallden | |
|
5f2c2f | 2003-11-25 | Anders Johansson | | RAISE_CACHE(INITIAL_CACHEABLE);
NO_PROTO_CACHE();
|
69a869 | 1999-05-18 | Per Hedbor | | return res;
}
|
93dd0e | 2000-07-27 | Johan Sundström | | mapping metadata( array|string|mapping data,
RequestID id,
int|void nodraw )
|
23b7ec | 2001-08-27 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
string na = store( data,id );
|
23b7ec | 2001-08-27 | Per Hedbor | | mapping res;
#ifdef ARG_CACHE_DEBUG
werror("meta %O\n", na );
#endif
if(! (res = restore_meta( na,id )) )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
if(nodraw)
return 0;
draw( na, id );
|
aea165 | 2001-06-26 | Per Hedbor | | return restore_meta( na,id );
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
23b7ec | 2001-08-27 | Per Hedbor | | return res;
|
2ff846 | 1999-09-02 | Per Hedbor | | }
mapping tomapp( mixed what )
{
if( mappingp( what ))
return what;
return ([ "":what ]);
}
string store( array|string|mapping data, RequestID id )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
6533f2 | 2001-08-23 | Martin Nilsson | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
aea165 | 2001-06-26 | Per Hedbor | | string ci, user;
|
83f54a | 2003-01-16 | Martin Stjernholm | | function update_args = lambda ( mapping a )
|
aea165 | 2001-06-26 | Per Hedbor | | {
if (!a->format)
|
f04b92 | 2000-09-13 | Jonas Wallden | |
#if constant(Image.GIF) && constant(Image.GIF.encode)
|
aea165 | 2001-06-26 | Per Hedbor | | a->format = "gif";
|
f04b92 | 2000-09-13 | Jonas Wallden | | #else
|
aea165 | 2001-06-26 | Per Hedbor | | a->format = "png";
|
f04b92 | 2000-09-13 | Jonas Wallden | | #endif
|
e89d02 | 2001-09-21 | Per Hedbor | | if( id->misc->authenticated_user &&
!id->misc->authenticated_user->is_transient )
|
aea165 | 2001-06-26 | Per Hedbor | |
a["\0u"] = user = id->misc->authenticated_user->name();
};
|
4afcd4 | 2001-08-09 | Per Hedbor | | if( mappingp( data ) )
{
|
aea165 | 2001-06-26 | Per Hedbor | | update_args( data );
|
2ff846 | 1999-09-02 | Per Hedbor | | ci = argcache->store( data );
|
4afcd4 | 2001-08-09 | Per Hedbor | | }
else if( arrayp( data ) )
{
|
aea165 | 2001-06-26 | Per Hedbor | | if( !mappingp( data[0] ) )
error("Expected mapping as the first element of the argument array\n");
update_args( data[0] );
|
93dd0e | 2000-07-27 | Johan Sundström | | ci = map( map( data, tomapp ), argcache->store )*"$";
|
f04b92 | 2000-09-13 | Jonas Wallden | | } else
|
2ff846 | 1999-09-02 | Per Hedbor | | ci = data;
|
83f54a | 2003-01-16 | Martin Stjernholm | | update_args = 0;
|
aea165 | 2001-06-26 | Per Hedbor | |
|
23b7ec | 2001-08-27 | Per Hedbor | | if( zero_type( uid_cache[ ci ] ) )
|
aea165 | 2001-06-26 | Per Hedbor | | {
uid_cache[ci] = user;
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | if( catch(QUERY("INSERT INTO "+name+" "
"(id,uid,atime) VALUES (%s,%s,UNIX_TIMESTAMP())",
ci, user||"")) )
QUERY( "UPDATE "+name+" SET uid=%s WHERE id=%s",
user||"", ci );
|
aea165 | 2001-06-26 | Per Hedbor | | }
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | |
|
29e7fe | 2001-11-27 | Marcus Wellhardh | | #ifndef NO_ARG_CACHE_SB_REPLICATE
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | if(id->misc->persistent_cache_crawler) {
foreach(ci/"$", string key) {
#if REPLICATE_DEBUG
werror("Request for id %O from prefetch crawler.\n", key);
|
07fbe1 | 2001-11-27 | Marcus Wellhardh | | #endif /* REPLICATE_DEBUG */
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | argcache->refresh_arg(key);
}
}
|
07fbe1 | 2001-11-27 | Marcus Wellhardh | | #endif /* NO_ARG_CACHE_SB_REPLICATE */
|
2ff846 | 1999-09-02 | Per Hedbor | | return ci;
}
void set_draw_function( function to )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
draw_function = to;
}
|
55fc49 | 2000-12-30 | Per Hedbor | | static void setup_tables()
{
|
4afcd4 | 2001-08-09 | Per Hedbor | | if(catch(QUERY("SELECT DATA FROM "+name+" WHERE id=''")))
|
55fc49 | 2000-12-30 | Per Hedbor | | {
|
aea165 | 2001-06-26 | Per Hedbor | | werror("Creating image-cache tables for '"+name+"'\n");
catch(QUERY("DROP TABLE "+name));
|
4afcd4 | 2001-08-09 | Per Hedbor | |
|
aea165 | 2001-06-26 | Per Hedbor | | catch(QUERY("DROP TABLE "+name+"_data"));
|
eae43a | 2001-08-13 | Per Hedbor | |
master()->resolv("DBManager.is_module_table")
( 0,"local",name,"Image cache for "+name);
|
21207e | 2001-06-13 | Per Hedbor | | QUERY("CREATE TABLE "+name+" ("
|
aea165 | 2001-06-26 | Per Hedbor | | "id CHAR(64) NOT NULL PRIMARY KEY, "
"size INT UNSIGNED NOT NULL DEFAULT 0, "
"uid CHAR(32) NOT NULL DEFAULT '', "
|
4afcd4 | 2001-08-09 | Per Hedbor | | "atime INT UNSIGNED NOT NULL DEFAULT 0,"
|
aea165 | 2001-06-26 | Per Hedbor | | "meta MEDIUMBLOB NOT NULL DEFAULT '',"
|
4afcd4 | 2001-08-09 | Per Hedbor | | "data MEDIUMBLOB NOT NULL DEFAULT '',"
"INDEX atime (atime)"
")" );
|
55fc49 | 2000-12-30 | Per Hedbor | | }
}
|
0b4177 | 2001-09-06 | Per Hedbor | | Sql.Sql get_db()
{
return dbm_cached_get("local");
}
|
03156d | 2001-01-29 | Per Hedbor | |
static void init_db( )
{
|
e7ac49 | 2003-04-06 | Anders Johansson | | catch(sync_meta());
|
aea165 | 2001-06-26 | Per Hedbor | | setup_tables();
|
03156d | 2001-01-29 | Per Hedbor | | }
|
5c1b62 | 2001-08-01 | Per Hedbor | | void do_cleanup( )
{
|
e7ac49 | 2003-04-06 | Anders Johansson | | background_run( 3600*10+random(4711), do_cleanup );
|
5c1b62 | 2001-08-01 | Per Hedbor | | flush(time()-7*3600*24);
}
|
55fc49 | 2000-12-30 | Per Hedbor | | void create( string id, function draw_func )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
55fc49 | 2000-12-30 | Per Hedbor | |
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
name = id;
draw_function = draw_func;
|
03156d | 2001-01-29 | Per Hedbor | | init_db();
|
e08221 | 2001-08-28 | Per Hedbor | |
|
03156d | 2001-01-29 | Per Hedbor | | master()->resolv( "DBManager.add_dblist_changed_callback" )( init_db );
|
5c1b62 | 2001-08-01 | Per Hedbor | |
|
e7ac49 | 2003-04-06 | Anders Johansson | | background_run( 10, do_cleanup );
}
void destroy()
{
if (mixed err = catch(sync_meta()))
report_warning("Failed to sync cached atimes for "+name+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | }
}
class ArgCache
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
0b4177 | 2001-09-06 | Per Hedbor | | #undef QUERY
#define QUERY(X,Y...) db->query(X,Y)
|
54f340 | 2001-09-06 | Per Hedbor | | Sql.Sql db;
|
6dde08 | 2001-08-20 | Per Hedbor | | string name;
|
2ff846 | 1999-09-02 | Per Hedbor | |
#define CACHE_VALUE 0
#define CACHE_SKEY 1
|
0e0008 | 2001-03-05 | Per Hedbor | | #define CACHE_SIZE 900
|
2ff846 | 1999-09-02 | Per Hedbor | | #define CLEAN_SIZE 100
|
a662d5 | 2000-12-31 | Per Hedbor | | static string lq, ulq;
|
678926 | 2001-09-06 | Per Hedbor | |
|
21207e | 2001-06-13 | Per Hedbor | | #ifdef THREADS
Thread.Mutex mutex = Thread.Mutex();
|
76fac8 | 2001-10-01 | Per Hedbor | |
# define LOCK() mixed __; catch( __ = mutex->lock() )
|
de4a0c | 2001-03-16 | Per Hedbor | | #else
# define LOCK()
#endif
|
2ff846 | 1999-09-02 | Per Hedbor | | static mapping (string:mixed) cache = ([ ]);
|
b870ac | 1999-09-03 | Henrik Grubbström (Grubba) | | static void setup_table()
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
af9bac | 2001-08-21 | Per Hedbor | | if(catch(QUERY("SELECT md5 FROM "+name+" WHERE id=0")))
|
eae43a | 2001-08-13 | Per Hedbor | | {
|
af9bac | 2001-08-21 | Per Hedbor | | master()->resolv("DBManager.is_module_table")
|
3c6764 | 2001-08-22 | Per Hedbor | | ( 0, "local", name,
|
af9bac | 2001-08-21 | Per Hedbor | | "The argument cache, used to map between "
"a short unique string and an argument "
"mapping" );
catch(QUERY("DROP TABLE "+name ));
|
19e34e | 2001-06-15 | Per Hedbor | | QUERY("CREATE TABLE "+name+" ("
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | "id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, "
"index_id INT UNSIGNED NULL DEFAULT NULL, "
"md5 CHAR(32) NOT NULL DEFAULT '', "
"atime INT UNSIGNED NOT NULL DEFAULT 0, "
"contents BLOB NOT NULL DEFAULT '', "
|
af9bac | 2001-08-21 | Per Hedbor | | "INDEX hind (md5))");
|
eae43a | 2001-08-13 | Per Hedbor | | }
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | |
if(catch(QUERY("SELECT index_id FROM "+name+" WHERE id=0")))
{
QUERY("ALTER TABLE "+name+" "
"ADD index_id INT UNSIGNED NULL DEFAULT NULL");
}
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
03156d | 2001-01-29 | Per Hedbor | | static void init_db()
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
2c0b61 | 2001-01-29 | Per Hedbor | |
|
03156d | 2001-01-29 | Per Hedbor | | cache = ([]);
|
0b4177 | 2001-09-06 | Per Hedbor | | db = dbm_cached_get("local");
|
a662d5 | 2000-12-31 | Per Hedbor | | setup_table( );
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
03156d | 2001-01-29 | Per Hedbor | | static void create( string _name )
{
name = _name;
init_db();
master()->resolv( "DBManager.add_dblist_changed_callback" )( init_db );
|
98eac9 | 2002-02-06 | Marcus Wellhardh | | get_plugins();
|
03156d | 2001-01-29 | Per Hedbor | | }
|
6dde08 | 2001-08-20 | Per Hedbor | | string read_args( int id )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
63c456 | 2001-09-06 | Per Hedbor | | LOCK();
|
19e34e | 2001-06-15 | Per Hedbor | | array res = QUERY("SELECT contents FROM "+name+" WHERE id="+id);
|
a662d5 | 2000-12-31 | Per Hedbor | | if( sizeof(res) )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
19e34e | 2001-06-15 | Per Hedbor | | QUERY("UPDATE "+name+" SET atime='"+time(1)+"' WHERE id="+id);
|
a662d5 | 2000-12-31 | Per Hedbor | | return res[0]->contents;
|
2ff846 | 1999-09-02 | Per Hedbor | | }
return 0;
}
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | int read_index_id( int id )
{
LOCK();
array res = QUERY("SELECT index_id FROM "+name+" WHERE id="+id);
if(sizeof(res) && res[0]->index_id)
return (int)res[0]->index_id;
return -1;
}
int create_key( string long_key, string|void md, int|void index_id )
|
af9bac | 2001-08-21 | Per Hedbor | | {
if( !md ) md = md5(long_key);
|
2c426e | 2002-02-01 | Henrik Grubbström (Grubba) | | LOCK();
|
af9bac | 2001-08-21 | Per Hedbor | | array data =
QUERY("SELECT id,contents FROM "+name+" WHERE md5=%s", md );
|
a662d5 | 2000-12-31 | Per Hedbor | | foreach( data, mapping m )
if( m->contents == long_key )
|
54f340 | 2001-09-06 | Per Hedbor | | return (int)m->id;
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | if(zero_type(index_id))
index_id = -1;
|
54f340 | 2001-09-06 | Per Hedbor | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | string index_id_value = (index_id == -1? "NULL": index_id);
QUERY( "INSERT INTO "+name+" (contents,md5,atime,index_id) VALUES "
"(%s,%s,UNIX_TIMESTAMP(),"+index_id_value+")", long_key, md );
|
54f340 | 2001-09-06 | Per Hedbor | | int id = (int)db->master_sql->insert_id();
|
8f2e82 | 2003-04-14 | Marcus Wellhardh | | if(!id)
error("ArgCache::create_key() insert_id returned 0.\n");
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | #ifdef REPLICATE_DEBUG
werror("Create new local key: id: %d, index_id: %d.\n", id, index_id);
#endif
|
44200a | 2001-08-22 | Per Hedbor | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | (plugins->create_key-({0}))( id, long_key );
|
af9bac | 2001-08-21 | Per Hedbor | |
|
3e2e09 | 2001-03-06 | Per Hedbor | | return id;
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
6dde08 | 2001-08-20 | Per Hedbor | |
|
387fa6 | 2001-03-05 | Per Hedbor | | static int low_key_exists( string key )
{
|
63c456 | 2001-09-06 | Per Hedbor | | LOCK();
int res = sizeof( QUERY( "SELECT id FROM "+name+" WHERE id="+(int)key));
if( res )
return res;
|
387fa6 | 2001-03-05 | Per Hedbor | | }
|
6dde08 | 2001-08-20 | Per Hedbor | | string secret;
|
387fa6 | 2001-03-05 | Per Hedbor | |
static void ensure_secret()
{
if( !secret )
secret = query( "argcache_secret" );
}
|
af9bac | 2001-08-21 | Per Hedbor | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | string encode_id( int a, int b, string|void server )
|
387fa6 | 2001-03-05 | Per Hedbor | | {
ensure_secret();
object crypto = Crypto.arcfour();
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | crypto->set_encrypt_key( server||secret );
|
af9bac | 2001-08-21 | Per Hedbor | | string res = crypto->crypt( a+"\327"+b );
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | |
res[0] |= 0x80;
|
387fa6 | 2001-03-05 | Per Hedbor | | res = Gmp.mpz( res, 256 )->digits( 36 );
return res;
}
|
af9bac | 2001-08-21 | Per Hedbor | |
|
3e2e09 | 2001-03-06 | Per Hedbor | | static array plugins;
static void get_plugins()
{
|
6dde08 | 2001-08-20 | Per Hedbor | | ensure_secret();
|
3e2e09 | 2001-03-06 | Per Hedbor | | plugins = ({});
foreach( ({ "../local/arg_cache_plugins", "arg_cache_plugins" }), string d)
if( file_stat( d ) )
|
270b2e | 2001-08-20 | Marcus Wellhardh | | foreach( glob("*.pike", get_dir( d )), string f )
|
6dde08 | 2001-08-20 | Per Hedbor | | {
object plug = ((program)(d+"/"+f))(this_object());
if( !plug->disabled )
plugins += ({ plug });
}
|
3e2e09 | 2001-03-06 | Per Hedbor | | }
static array plugin_decode_id( string id )
{
mixed r;
foreach( (plugins->decode_id-({0})), function(string:array(int)) f )
if( r = f( id ) )
return r;
return 0;
}
|
2ff846 | 1999-09-02 | Per Hedbor | |
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | | array(int) low_decode_id(string a, string key)
|
387fa6 | 2001-03-05 | Per Hedbor | | {
|
3c6764 | 2001-08-22 | Per Hedbor | | if( catch( a = Gmp.mpz( a, 36 )->digits( 256 ) ) )
return 0;
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | | object crypto = Crypto.arcfour();
crypto->set_encrypt_key(key);
|
f4c4cf | 2002-02-06 | Henrik Grubbström (Grubba) | | string msg = crypto->crypt(a);
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | |
|
f4c4cf | 2002-02-06 | Henrik Grubbström (Grubba) | | msg[0] &= 0x7f;
|
387fa6 | 2001-03-05 | Per Hedbor | | int i, j;
|
f4c4cf | 2002-02-06 | Henrik Grubbström (Grubba) | | if((sscanf(msg, "%d\327%d", i, j) == 2) &&
(msg == i + "\327" + j)) {
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | | return ({ i, j });
}
|
f4c4cf | 2002-02-06 | Henrik Grubbström (Grubba) | | #ifndef NO_BROKEN_ARGCACHE_FALLBACK
crypto->set_encrypt_key(key);
msg = crypto->crypt("\0"+a);
if((sscanf(msg, "%d\327%d", i, j) == 2) &&
(msg == i + "\327" + j)) {
return ({ i, j });
}
#endif /* !NO_BROKEN_ARGCACHE_FALLBACK */
|
b579b4 | 2002-02-06 | Henrik Grubbström (Grubba) | | return 0;
}
static array(int) decode_id( string a )
{
array(int) res;
ensure_secret();
if (res = low_decode_id(a, secret)) {
return res;
}
return plugin_decode_id(a);
|
387fa6 | 2001-03-05 | Per Hedbor | | }
|
2ff846 | 1999-09-02 | Per Hedbor | | int key_exists( string key )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
de4a0c | 2001-03-16 | Per Hedbor | | if( cache[key] ) return 1;
|
387fa6 | 2001-03-05 | Per Hedbor | | array i = decode_id( key );
if(!i) return 0;
return low_key_exists( i[0] ) && low_key_exists( i[1] );
|
2ff846 | 1999-09-02 | Per Hedbor | | }
string store( mapping args )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
2ff846 | 1999-09-02 | Per Hedbor | | array b = values(args), a = sort(indices(args),b);
|
678926 | 2001-09-06 | Per Hedbor | | LOCK();
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | int index_id = low_store( a );
string id = encode_id( index_id, low_store( b, index_id ) );
|
10bb98 | 2001-03-16 | Per Hedbor | | if( !cache[ id ] )
cache[ id ] = args+([]);
|
387fa6 | 2001-03-05 | Per Hedbor | | return id;
}
|
2ff846 | 1999-09-02 | Per Hedbor | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | int low_store( array a, int|void index_id )
|
387fa6 | 2001-03-05 | Per Hedbor | | {
|
10bb98 | 2001-03-16 | Per Hedbor | | string data = encode_value_canonic( a );
|
af9bac | 2001-08-21 | Per Hedbor | | string hv = md5( data );
|
0e0008 | 2001-03-05 | Per Hedbor | | if( mixed q = cache[ hv ] )
return q;
|
eae43a | 2001-08-13 | Per Hedbor | |
|
0e0008 | 2001-03-05 | Per Hedbor | | #ifdef THREADS
if( mixed q = cache[ hv ] )
return q;
#endif
|
8693b2 | 2000-01-08 | Martin Stjernholm | | if( sizeof( cache ) >= CACHE_SIZE )
|
af9bac | 2001-08-21 | Per Hedbor | | cache = ([]);
|
8693b2 | 2000-01-08 | Martin Stjernholm | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | int id = create_key( data, hv, index_id );
|
0e0008 | 2001-03-05 | Per Hedbor | | cache[ hv ] = id;
cache[ id ] = a;
|
2ff846 | 1999-09-02 | Per Hedbor | | return id;
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
3e2e09 | 2001-03-06 | Per Hedbor | | mapping lookup( string id )
|
c3a53d | 1999-06-25 | Per Hedbor | | {
|
de4a0c | 2001-03-16 | Per Hedbor | | if( cache[id] )
return cache[id]+([]);
|
387fa6 | 2001-03-05 | Per Hedbor | | array i = decode_id( id );
|
44200a | 2001-08-22 | Per Hedbor | | if( !i )
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | error("Requesting unknown key (decode failed)\n");
|
387fa6 | 2001-03-05 | Per Hedbor | | array a = low_lookup( i[0] );
array b = low_lookup( i[1] );
|
84d751 | 2003-01-13 | Martin Stjernholm | | if (!arrayp (a) || !arrayp (b) || sizeof (a) != sizeof (b))
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | {
|
84d751 | 2003-01-13 | Martin Stjernholm | |
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | #ifdef ARG_CACHE_DEBUG
werror("lookup(%O) a: %O, b: %O\n", id, a, b);
#endif
error("Requesting unknown key (size missmatch)\n");
}
|
84d751 | 2003-01-13 | Martin Stjernholm | | return (cache[id] = mkmapping( a, b ))+([]);
|
387fa6 | 2001-03-05 | Per Hedbor | | }
|
6dde08 | 2001-08-20 | Per Hedbor | | array low_lookup( int id )
|
387fa6 | 2001-03-05 | Per Hedbor | | {
mixed v;
|
0e0008 | 2001-03-05 | Per Hedbor | | if( v = cache[id] )
return v;
|
2ff846 | 1999-09-02 | Per Hedbor | | string q = read_args( id );
|
3e2e09 | 2001-03-06 | Per Hedbor | | if( !q )
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | error("Requesting unknown key (not found in db)\n");
|
a662d5 | 2000-12-31 | Per Hedbor | | mixed data = decode_value(q);
|
de4a0c | 2001-03-16 | Per Hedbor | | string hl = Crypto.md5()->update( q )->digest();
cache[ hl ] = id;
|
0e0008 | 2001-03-05 | Per Hedbor | | cache[ id ] = data;
|
2ff846 | 1999-09-02 | Per Hedbor | | return data;
|
c3a53d | 1999-06-25 | Per Hedbor | | }
|
2ff846 | 1999-09-02 | Per Hedbor | | void delete( string id )
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
8f2e82 | 2003-04-14 | Marcus Wellhardh | | LOCK();
|
3e2e09 | 2001-03-06 | Per Hedbor | | (plugins->delete-({0}))( id );
|
387fa6 | 2001-03-05 | Per Hedbor | | m_delete( cache, id );
|
0e0008 | 2001-03-05 | Per Hedbor | | foreach( decode_id( id ), int id )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
3e2e09 | 2001-03-06 | Per Hedbor | | (plugins->low_delete-({0}))( id );
|
387fa6 | 2001-03-05 | Per Hedbor | | if(cache[id])
{
m_delete( cache, cache[id] );
m_delete( cache, id );
}
|
19e34e | 2001-06-15 | Per Hedbor | | QUERY( "DELETE FROM "+name+" WHERE id="+id );
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | |
|
4777a9 | 2005-02-01 | Marcus Wellhardh | | #define SECRET_TAG "££"
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | int write_dump(Stdio.File file, int|void from_time)
{
|
cb7b23 | 2004-02-09 | Marcus Wellhardh | | constant FETCH_ROWS = 10000;
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | |
|
4777a9 | 2005-02-01 | Marcus Wellhardh | | string encoded_secret = SECRET_TAG+MIME.encode_base64(secret, 1)+"\n";
if(sizeof(encoded_secret) != file->write(encoded_secret))
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | return 0;
|
cb7b23 | 2004-02-09 | Marcus Wellhardh | |
if( !has_value((plugins->is_functional-({0}))(), 1) )
{
int cursor;
array(int) ids;
do {
if(from_time)
ids =
(array(int))
QUERY( "SELECT id from "+name+
" WHERE atime >= %d "
" AND index_id IS NOT NULL"
" LIMIT %d, %d", from_time, cursor, FETCH_ROWS)->id;
else
ids =
(array(int))
QUERY( "SELECT id from "+name+
" LIMIT %d, %d", cursor, FETCH_ROWS)->id;
cursor += FETCH_ROWS;
foreach(ids, int id) {
int index_id = read_index_id(id);
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | #ifdef REPLICATE_DEBUG
|
cb7b23 | 2004-02-09 | Marcus Wellhardh | | werror("write_dump: argcache id: %d, index_id: %d.\n", id, index_id);
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | #endif
|
cb7b23 | 2004-02-09 | Marcus Wellhardh | |
string s =
MIME.encode_base64(encode_value(({ id, read_args(id),
index_id, read_args(index_id) })),
1)+"\n";
if(sizeof(s) != file->write(s))
return 0;
}
} while(sizeof(ids) == FETCH_ROWS);
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | }
return file->write("EOF\n") == 4;
}
static void create_remote_key(int id, string key,
int index_id, string index_key,
string server)
{
(plugins->create_remote_key-({0}))( id, key, index_id, index_key, server );
}
string read_dump (Stdio.FILE file)
{
string secret = file->gets();
|
4777a9 | 2005-02-01 | Marcus Wellhardh | |
if(secret && has_prefix(secret, SECRET_TAG))
secret = MIME.decode_base64(secret[sizeof(SECRET_TAG)..]);
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | if(!secret || !sizeof(secret))
return "Server secret is missing\n";
string s;
while(s = file->gets())
{
if(s == "EOF")
return 0;
array a;
if(catch {
a = decode_value(MIME.decode_base64(s));
}) return "Decode failed for argcache record\n";
if(sizeof(a) != 4)
return "Decode failed for argcache record (wrong size on key array)\n";
#ifdef REPLICATE_DEBUG
werror("read_dump: argcache id: %d, index_id: %d.\n", a[0], a[2]);
#endif
create_remote_key(a[0], a[1], a[2], a[3], secret);
}
if(s != "EOF")
return "Missing data in argcache file\n";
return 0;
}
void refresh_arg(string id)
{
array i = decode_id( id );
if( !i )
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | error("Requesting unknown key (decode failed)\n");
|
8f2e82 | 2003-04-14 | Marcus Wellhardh | | LOCK();
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | QUERY("UPDATE "+name+" SET atime='"+time(1)+"' WHERE id="+i[0]);
QUERY("UPDATE "+name+" SET atime='"+time(1)+"' WHERE id="+i[1]);
}
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
69a869 | 1999-05-18 | Per Hedbor | |
|
95b69e | 1999-09-05 | Per Hedbor | | mapping cached_decoders = ([]);
string decode_charset( string charset, string data )
{
|
808e17 | 1999-09-05 | Henrik Grubbström (Grubba) | |
|
95b69e | 1999-09-05 | Per Hedbor | | if( charset == "iso-8859-1" ) return data;
if( !cached_decoders[ charset ] )
cached_decoders[ charset ] = Locale.Charset.decoder( charset );
data = cached_decoders[ charset ]->feed( data )->drain();
|
dc3a47 | 1999-12-15 | Marcus Comstedt | | cached_decoders[ charset ]->clear();
|
95b69e | 1999-09-05 | Per Hedbor | | return data;
}
|
2ff846 | 1999-09-02 | Per Hedbor | | void create()
{
|
23414a | 2000-07-21 | Andreas Lange | |
#define __REG_PROJ Locale.register_project
|
0569fa | 2001-09-29 | Martin Nilsson | | __REG_PROJ("roxen_""start", "translations/%L/roxen_start.xml");
__REG_PROJ("roxen_""config", "translations/%L/roxen_config.xml");
__REG_PROJ("roxen_""message", "translations/%L/roxen_message.xml");
__REG_PROJ("admin_""tasks", "translations/%L/admin_tasks.xml");
|
c12fcc | 2001-01-01 | Martin Nilsson | | Locale.set_default_project_path("translations/%L/%P.xml");
|
23414a | 2000-07-21 | Andreas Lange | | #undef __REG_PROJ
|
5629e6 | 2000-07-11 | Andreas Lange | | define_global_variables();
|
cde8d6 | 2000-02-16 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | |
|
d3b98e | 1999-11-28 | Per Hedbor | |
|
61020e | 2005-11-14 | Martin Stjernholm | | #if constant (Protocols.LDAP.FilterError)
add_constant ("NewLDAP", Protocols.LDAP);
#else
add_constant ("NewLDAP", _NewLDAP);
#endif
|
6fa4d1 | 2001-02-23 | Per Hedbor | | add_constant( "CFUserDBModule",config_userdb_module );
|
50b697 | 2001-08-31 | Per Hedbor | |
|
27008b | 2000-03-20 | Martin Stjernholm | |
|
2ff846 | 1999-09-02 | Per Hedbor | |
|
4ed099 | 2003-01-15 | Henrik Grubbström (Grubba) | | if (all_constants()["roxen"]) {
error("Duplicate Roxen object!\n");
}
|
50b697 | 2001-08-31 | Per Hedbor | |
|
95b69e | 1999-09-05 | Per Hedbor | | add_constant( "roxen", this_object());
|
27008b | 2000-03-20 | Martin Stjernholm | |
|
855c39 | 1999-11-29 | Per Hedbor | |
|
2c0b61 | 2001-01-29 | Per Hedbor | |
|
c08c16 | 2001-01-02 | Per Hedbor | |
|
b52e86 | 2001-08-24 | Martin Stjernholm | |
master()->resolv ("RXML.refs");
master()->resolv ("RXML.PXml");
master()->resolv ("RXML.PEnt");
foreach(({ "module.pmod","PEnt.pike", "PExpr.pike","PXml.pike",
"refs.pmod","utils.pmod" }), string q )
dump( "etc/modules/RXML.pmod/"+ q );
dump( "etc/modules/RXML.pmod/module.pmod" );
|
5574b2 | 2002-05-06 | Martin Stjernholm | | master()->add_dump_constant ("RXML.empty_tag_set",
master()->resolv ("RXML.empty_tag_set"));
|
b52e86 | 2001-08-24 | Martin Stjernholm | |
dump( "etc/roxen_master.pike" );
dump( "etc/modules/Roxen.pmod" );
dump( "base_server/config_userdb.pike" );
dump( "base_server/disk_cache.pike" );
dump( "base_server/roxen.pike" );
dump( "base_server/basic_defvar.pike" );
dump( "base_server/newdecode.pike" );
dump( "base_server/read_config.pike" );
dump( "base_server/global_variables.pike" );
dump( "base_server/module_support.pike" );
dump( "base_server/socket.pike" );
dump( "base_server/cache.pike" );
dump( "base_server/supports.pike" );
dump( "base_server/hosts.pike");
dump( "base_server/language.pike");
|
db47c9 | 2001-08-24 | Martin Stjernholm | | #ifndef __NT__
if(!getuid())
add_constant("Privs", Privs);
else
#endif /* !__NT__ */
add_constant("Privs", class {
void create(string reason, int|string|void uid, int|string|void gid) {}
});
DDUMP( "base_server/roxenlib.pike");
DDUMP( "etc/modules/Dims.pmod");
DDUMP( "config_interface/boxes/Box.pmod" );
|
50b697 | 2001-08-31 | Per Hedbor | | dump( "base_server/html.pike");
|
db47c9 | 2001-08-24 | Martin Stjernholm | | add_constant( "RoxenModule", RoxenModule);
add_constant( "ModuleInfo", ModuleInfo );
add_constant( "load", load);
|
50b697 | 2001-08-31 | Per Hedbor | |
|
db47c9 | 2001-08-24 | Martin Stjernholm | | add_constant( "Roxen.set_locale", set_locale );
add_constant( "Roxen.get_locale", get_locale );
add_constant( "roxen.locale", locale );
|
2c0b61 | 2001-01-29 | Per Hedbor | |
|
9a8a15 | 2000-09-25 | Per Hedbor | | _configuration = (program)"configuration";
|
7e596b | 2000-02-13 | Per Hedbor | | dump( "base_server/configuration.pike" );
dump( "base_server/rxmlhelp.pike" );
|
2c0b61 | 2001-01-29 | Per Hedbor | |
add_constant( "Configuration", _configuration );
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
55a866 | 2000-11-20 | Per Hedbor | | mixed get_locale( )
{
return locale->get();
}
|
aa7872 | 2001-08-24 | Martin Stjernholm | | int set_u_and_gid (void|int from_handler_thread)
|
93dd0e | 2000-07-27 | Johan Sundström | |
|
2ff846 | 1999-09-02 | Per Hedbor | | {
#ifndef __NT__
string u, g;
int uid, gid;
array pw;
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (from_handler_thread && geteuid()) {
#ifdef TEST_EUID_CHANGE
werror ("euid change effective in handler thread.\n");
#endif
return 1;
}
|
8552d9 | 2001-01-13 | Martin Nilsson | | u=query("User");
|
2ff846 | 1999-09-02 | Per Hedbor | | sscanf(u, "%s:%s", u, g);
if(strlen(u))
{
if(getuid())
{
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (!from_handler_thread)
|
81f1a4 | 2002-02-27 | Martin Stjernholm | | report_error(LOC_M(24, "It is possible to change uid and gid only "
|
aa7872 | 2001-08-24 | Martin Stjernholm | | "if the server is running as root.")+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | } else {
|
aa7872 | 2001-08-24 | Martin Stjernholm | | #ifdef TEST_EUID_CHANGE
if (Stdio.write_file ("rootonly",
"Only root should be able to read this.\n",
0600))
test_euid_change = 1;
#endif
|
2ff846 | 1999-09-02 | Per Hedbor | | if (g) {
#if constant(getgrnam)
pw = getgrnam (g);
if (!pw)
if (sscanf (g, "%d", gid)) pw = getgrgid (gid), g = (string) gid;
else report_error ("Couldn't resolve group " + g + ".\n"), g = 0;
if (pw) g = pw[0], gid = pw[2];
|
a22f6f | 1999-05-12 | Per Hedbor | | #else
|
2ff846 | 1999-09-02 | Per Hedbor | | if (!sscanf (g, "%d", gid))
report_warning ("Can't resolve " + g + " to gid on this system; "
"numeric gid required.\n");
|
a22f6f | 1999-05-12 | Per Hedbor | | #endif
|
2ff846 | 1999-09-02 | Per Hedbor | | }
|
a22f6f | 1999-05-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | pw = getpwnam (u);
if (!pw)
if (sscanf (u, "%d", uid)) pw = getpwuid (uid), u = (string) uid;
else {
report_error ("Couldn't resolve user " + u + ".\n");
return 0;
}
if (pw) {
u = pw[0], uid = pw[2];
if (!g) gid = pw[3];
}
|
a22f6f | 1999-05-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | #ifdef THREADS
|
3e3bab | 2001-01-19 | Per Hedbor | | Thread.MutexKey mutex_key;
|
aa7872 | 2001-08-24 | Martin Stjernholm | | object threads_disabled;
if (!from_handler_thread) {
catch { mutex_key = euid_egid_lock->lock(); };
threads_disabled = _disable_threads();
}
|
2ff846 | 1999-09-02 | Per Hedbor | | #endif
|
a22f6f | 1999-05-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | #if constant(seteuid)
if (geteuid() != getuid()) seteuid (getuid());
#endif
|
a22f6f | 1999-05-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | #if constant(initgroups)
catch {
initgroups(pw[0], gid);
};
#endif
|
8552d9 | 2001-01-13 | Martin Nilsson | | if (query("permanent_uid")) {
|
2ff846 | 1999-09-02 | Per Hedbor | | #if constant(setuid)
if (g) {
# if constant(setgid)
setgid(gid);
|
23414a | 2000-07-21 | Andreas Lange | | if (getgid() != gid) {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(25, "Failed to set gid.")+"\n");
|
23414a | 2000-07-21 | Andreas Lange | | g = 0;
}
|
2ff846 | 1999-09-02 | Per Hedbor | | # else
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (!from_handler_thread)
report_warning(LOC_M(26, "Setting gid not supported on this system.")
+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | g = 0;
# endif
}
setuid(uid);
|
23414a | 2000-07-21 | Andreas Lange | | if (getuid() != uid) {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(27, "Failed to set uid.")+"\n");
|
23414a | 2000-07-21 | Andreas Lange | | u = 0;
}
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (u && !from_handler_thread)
report_notice(CALL_M("setting_uid_gid_permanently", "eng")
(uid, gid, u, g));
|
2ff846 | 1999-09-02 | Per Hedbor | | #else
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (!from_handler_thread)
report_warning(LOC_M(28, "Setting uid not supported on this system.")
+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | u = g = 0;
#endif
}
|
b84a16 | 1999-06-07 | Martin Stjernholm | | else {
|
2ff846 | 1999-09-02 | Per Hedbor | | #if constant(seteuid)
if (g) {
# if constant(setegid)
setegid(gid);
|
23414a | 2000-07-21 | Andreas Lange | | if (getegid() != gid) {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(29, "Failed to set effective gid.")+"\n");
|
23414a | 2000-07-21 | Andreas Lange | | g = 0;
}
|
2ff846 | 1999-09-02 | Per Hedbor | | # else
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (!from_handler_thread)
report_warning(LOC_M(30, "Setting effective gid not supported on "
"this system.")+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | g = 0;
# endif
}
seteuid(uid);
|
23414a | 2000-07-21 | Andreas Lange | | if (geteuid() != uid) {
|
c8ee71 | 2000-09-09 | Andreas Lange | | report_error(LOC_M(31, "Failed to set effective uid.")+"\n");
|
23414a | 2000-07-21 | Andreas Lange | | u = 0;
}
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (u && !from_handler_thread)
report_notice(CALL_M("setting_uid_gid", "eng")(uid, gid, u, g));
|
2ff846 | 1999-09-02 | Per Hedbor | | #else
|
aa7872 | 2001-08-24 | Martin Stjernholm | | if (!from_handler_thread)
report_warning(LOC_M(32, "Setting effective uid not supported on "
"this system.")+"\n");
|
2ff846 | 1999-09-02 | Per Hedbor | | u = g = 0;
#endif
|
b84a16 | 1999-06-07 | Martin Stjernholm | | }
|
2ff846 | 1999-09-02 | Per Hedbor | |
|
0217b8 | 2003-03-03 | Henrik Grubbström (Grubba) | | enable_coredumps(1);
|
ab0cb1 | 2001-09-27 | Anders Johansson | | #ifdef THREADS
|
996384 | 2001-09-26 | Martin Stjernholm | |
mutex_key = 0;
threads_disabled = 0;
|
ab0cb1 | 2001-09-27 | Anders Johansson | | #endif
|
996384 | 2001-09-26 | Martin Stjernholm | |
|
2ff846 | 1999-09-02 | Per Hedbor | | return !!u;
|
a22f6f | 1999-05-12 | Per Hedbor | | }
}
|
2ff846 | 1999-09-02 | Per Hedbor | | #endif
return 0;
}
|
a22f6f | 1999-05-12 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | void reload_all_configurations()
{
|
4c12d7 | 2000-12-10 | Per Hedbor | | Configuration conf;
|
2ff846 | 1999-09-02 | Per Hedbor | | array (object) new_confs = ({});
mapping config_cache = ([]);
int modified;
setvars(retrieve("Variables", 0));
|
e08221 | 2001-08-28 | Per Hedbor | |
|
2ff846 | 1999-09-02 | Per Hedbor | | foreach(list_all_configurations(), string config)
|
a22f6f | 1999-05-12 | Per Hedbor | | {
|
1f4a6c | 2000-08-28 | Per Hedbor | | mixed err;
Stat st;
|
4cf783 | 2000-02-16 | Per Hedbor | | conf = find_configuration( config );
|
2ff846 | 1999-09-02 | Per Hedbor | | i |