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 | |
|
96af3e | 2009-03-23 | Henrik Grubbström (Grubba) | | constant cvs_version="$Id: roxen.pike,v 1.1026 2009/03/23 12:51:13 jonasw 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>
|
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
|
4029da | 2007-03-02 | Henrik Grubbström (Grubba) | | #ifdef SMTP_RELAY
inherit "smtprelay";
#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 | |
|
a28eca | 2009-01-11 | Martin Stjernholm | |
|
79c3a6 | 2001-04-25 | Jonas Wallden | | Thread.Thread backend_thread;
|
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)
#else
#define enable_coredumps(X)
#endif
|
851483 | 2000-11-27 | Per Hedbor | | #define DDUMP(X) sol( combine_path( __FILE__, "../../" + X ), dump )
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected function sol = master()->set_on_load;
|
851483 | 2000-11-27 | Per Hedbor | |
|
32cd1c | 2008-10-13 | Martin Stjernholm | |
constant pike_cycle_depth = 0;
|
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 )
{
|
4e3207 | 2009-01-09 | Stephen R. van den Berg | | return Gmp.mpz(Crypto.MD5.hash( what ),256)->digits(32);
|
50b697 | 2001-08-31 | Per Hedbor | | }
|
970e24 | 2000-09-12 | Per Hedbor | | string query_configuration_dir()
{
return configuration_dir;
}
|
855c39 | 1999-11-29 | Per Hedbor | |
|
f49478 | 2008-10-02 | Martin Stjernholm | | array(string|int) filename_2 (program|object o)
|
95b69e | 1999-09-05 | Per Hedbor | | {
|
596425 | 1999-11-19 | Per Hedbor | | if( objectp( o ) )
o = object_program( o );
|
f49478 | 2008-10-02 | Martin Stjernholm | | string fname = Program.defined (o);
int line;
if (fname) {
array(string) p = fname / ":";
if (sizeof (p) > 1 && p[-1] != "" && sscanf (p[-1], "%d%*c", int l) == 1) {
fname = p[..<1] * ":";
line = l;
}
}
else if( !fname ) {
fname = master()->program_name( o );
if (!fname)
return ({0, 0});
}
string cwd = getcwd() + "/";
if (has_prefix (fname, cwd))
fname = fname[sizeof (cwd)..];
return ({fname, line});
}
string filename( program|object o )
{
[string fname, int line] = filename_2 (o);
return fname || "(unknown program)";
|
95b69e | 1999-09-05 | Per Hedbor | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int once_mode;
|
b21503 | 2004-05-04 | Henrik Grubbström (Grubba) | |
|
8cbc5f | 2002-09-03 | Martin Stjernholm | |
|
3be6fd | 2006-10-30 | Martin Stjernholm | | array(string) compat_levels = ({"2.1", "2.2", "2.4", "2.5",
"3.3", "3.4",
|
1f6b0c | 2008-12-23 | Martin Stjernholm | | "4.0", "4.5",
"5.0"});
|
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 )
{
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;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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
|
fc4039 | 2008-08-15 | Martin Stjernholm | | private string _getcwd()
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | {
if (catch{return(getcwd());}) {
return("Unknown directory (no x-bit on current directory?)");
}
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | private string dbt(array t)
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | {
if(!arrayp(t) || (sizeof(t)<2)) return "";
return (((t[0]||"Unknown program")-(_getcwd()+"/"))-"base_server/")+":"+t[1]+"\n";
}
#ifdef THREADS
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mixed mutex_key;
protected 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) {
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch { mutex_key = euid_egid_lock->lock(); })
werror (describe_backtrace (err));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
|
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)
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch { cleargroups(); })
werror (describe_backtrace (err));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* cleargroups */
#if efun(initgroups)
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch { initgroups(u[0], u[3]); })
werror (describe_backtrace (err));
|
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) {
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch {
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | 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) | | }
|
d307c7 | 2008-08-06 | Martin Stjernholm | | })
werror (describe_backtrace (err));
|
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)
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch { cleargroups(); })
werror (describe_backtrace (err));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | #endif /* cleargroups */
if(u && (sizeof(u) > 3)) {
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch { initgroups(u[0], u[3]); })
werror (describe_backtrace (err));
|
0f8b2f | 1999-03-27 | Henrik Grubbström (Grubba) | | }
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) | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch (stop_handler_threads()))
werror (describe_backtrace (err));
|
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) | |
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err =
catch { report_notice("Shutting down MySQL.\n"); } ||
catch {
Sql.Sql db = connect_to_my_mysql(0, "mysql");
db->shutdown();
})
werror (describe_backtrace (err));
|
c7ca24 | 2004-03-09 | Henrik Grubbström (Grubba) | | }
|
532b90 | 2001-08-13 | Martin Stjernholm | | destruct (cache);
|
8de870 | 2004-08-23 | Martin Stjernholm | | #if 0
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch {
if (exit_code && !once_mode)
report_notice("Restarting Roxen.\n");
else
report_notice("Shutting down Roxen.\n");
})
werror (describe_backtrace (err));
|
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) | | }
|
f931d7 | 2008-09-29 | Martin Stjernholm | | private int shutdown_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) | | {
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if(shutdown_recurse >= 4)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err =
catch (report_notice("Exiting roxen (spurious signals received).\n")) ||
catch (stop_all_configurations()))
werror (describe_backtrace (err));
|
532b90 | 2001-08-13 | Martin Stjernholm | | destruct(cache);
|
e83c43 | 2001-03-11 | Martin Nilsson | | #ifdef THREADS
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch (stop_handler_threads()))
werror (describe_backtrace (err));
|
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 | | }
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if (shutdown_recurse++) return;
|
dde979 | 2008-09-30 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | |
slow_be_timeout_changed();
|
dde979 | 2008-09-30 | Martin Stjernholm | | #endif
|
e83c43 | 2001-03-11 | Martin Nilsson | |
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch(stop_all_configurations()))
werror (describe_backtrace (err));
|
79b7c3 | 2001-09-13 | Honza Petrous | |
|
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 | | }
|
d47483 | 2008-10-26 | Martin Stjernholm | | private int shutdown_started;
|
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 | | {
|
d47483 | 2008-10-26 | Martin Stjernholm | | shutdown_started = 1;
|
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 | | {
|
d47483 | 2008-10-26 | Martin Stjernholm | | shutdown_started = 1;
|
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()
{
|
d47483 | 2008-10-26 | Martin Stjernholm | | shutdown_started = 1;
|
1d71a0 | 2009-02-11 | Jonas Wallden | | report_notice("Interrupt request received.\n");
|
e83c43 | 2001-03-11 | Martin Nilsson | | low_shutdown(-1);
}
|
d47483 | 2008-10-26 | Martin Stjernholm | | int is_shutting_down()
{
return shutdown_started;
}
|
e83c43 | 2001-03-11 | Martin Nilsson | |
|
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();
}
}
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
protected Pike.Backend slow_req_monitor;
|
f931d7 | 2008-09-29 | Martin Stjernholm | | protected float slow_req_timeout, slow_be_timeout;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | |
protected void slow_req_monitor_thread (Pike.Backend my_monitor)
{
while (slow_req_monitor == my_monitor)
slow_req_monitor (3600);
}
|
f931d7 | 2008-09-29 | Martin Stjernholm | | protected mixed slow_be_call_out;
protected void slow_be_before_cb()
{
#ifdef DEBUG
if (this_thread() != backend_thread) error ("Run from wrong thread.\n");
#endif
if (Pike.Backend monitor = slow_be_call_out && slow_req_monitor) {
monitor->remove_call_out (slow_be_call_out);
slow_be_call_out = 0;
}
}
protected void slow_be_after_cb()
{
#ifdef DEBUG
if (this_thread() != backend_thread) error ("Run from wrong thread.\n");
#endif
if (slow_be_timeout > 0.0)
if (Pike.Backend monitor = slow_req_monitor)
slow_be_call_out = monitor->call_out (dump_slow_req, slow_be_timeout,
this_thread(), slow_be_timeout);
}
|
0be325 | 2008-09-25 | Martin Stjernholm | | void slow_req_count_changed()
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | {
Pike.Backend monitor = slow_req_monitor;
|
0be325 | 2008-09-25 | Martin Stjernholm | | int count = query ("slow_req_bt_count");
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | |
|
0be325 | 2008-09-25 | Martin Stjernholm | | if (count && monitor) {
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
|
0be325 | 2008-09-25 | Martin Stjernholm | | else if (count) {
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | monitor = slow_req_monitor = Pike.SmallBackend();
Thread.thread_create (slow_req_monitor_thread, monitor);
monitor->call_out (lambda () {}, 0);
|
f931d7 | 2008-09-29 | Martin Stjernholm | | slow_be_timeout_changed();
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
else if (monitor) {
slow_req_monitor = 0;
monitor->call_out (lambda () {}, 0);
|
f931d7 | 2008-09-29 | Martin Stjernholm | | slow_be_timeout_changed();
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
}
|
0be325 | 2008-09-25 | Martin Stjernholm | | void slow_req_timeout_changed()
{
#ifdef DEBUG
if (query ("slow_req_bt_timeout") < 0) error ("Invalid timeout.\n");
#endif
slow_req_timeout = query ("slow_req_bt_timeout");
}
|
f931d7 | 2008-09-29 | Martin Stjernholm | | void slow_be_timeout_changed()
{
#ifdef DEBUG
if (query ("slow_be_bt_timeout") < 0) error ("Invalid timeout.\n");
#endif
slow_be_timeout = query ("slow_be_bt_timeout");
#ifdef DEBUG
if ((Pike.DefaultBackend->before_callback &&
Pike.DefaultBackend->before_callback != slow_be_before_cb) ||
(Pike.DefaultBackend->after_callback &&
Pike.DefaultBackend->after_callback != slow_be_after_cb))
werror ("Pike.DefaultBackend already hooked up with "
"other before/after callbacks - they get overwritten: %O/%O\n",
Pike.DefaultBackend->before_callback,
Pike.DefaultBackend->after_callback);
#endif
if (query ("slow_req_bt_count") && slow_be_timeout > 0.0 &&
|
d47483 | 2008-10-26 | Martin Stjernholm | | !shutdown_started) {
|
f931d7 | 2008-09-29 | Martin Stjernholm | | Pike.DefaultBackend->before_callback = slow_be_before_cb;
Pike.DefaultBackend->after_callback = slow_be_after_cb;
}
else {
Pike.DefaultBackend->before_callback = 0;
Pike.DefaultBackend->after_callback = 0;
if (Pike.Backend monitor = slow_be_call_out && slow_req_monitor) {
monitor->remove_call_out (slow_be_call_out);
slow_be_call_out = 0;
}
}
}
|
824392 | 2008-09-22 | Martin Stjernholm | | protected void dump_slow_req (Thread.Thread thread, float timeout)
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | {
|
f931d7 | 2008-09-29 | Martin Stjernholm | | object threads_disabled = _disable_threads();
|
0be325 | 2008-09-25 | Martin Stjernholm | | int count = query ("slow_req_bt_count");
if (count > 0) set ("slow_req_bt_count", count - 1);
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if (thread == backend_thread && !slow_be_call_out) {
}
else {
report_debug ("###### %s 0x%x has been busy for more than %g seconds.\n",
thread == backend_thread ? "Backend thread" : "Thread",
thread->id_number(), timeout);
|
5b5c80 | 2008-09-29 | Martin Stjernholm | | describe_all_threads (0, threads_disabled);
|
f931d7 | 2008-09-29 | Martin Stjernholm | | }
threads_disabled = 0;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
#endif // !NO_SLOW_REQ_BT
|
4c3c53 | 2001-08-09 | Per Hedbor | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | local protected Queue handle_queue = Queue();
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
172054 | 1998-10-04 | Henrik Grubbström (Grubba) | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | local protected int thread_reap_cnt;
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int threads_on_hold;
|
9567c1 | 2001-02-23 | Martin Stjernholm | |
|
14179b | 1997-01-29 | Per Hedbor | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | local protected 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;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | Pike.Backend monitor;
mixed call_out;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #endif
|
4f4bc1 | 1998-02-04 | Per Hedbor | | if(q=catch {
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | do {
|
4eb319 | 2001-09-02 | Martin Stjernholm | |
|
1bcd22 | 2007-09-06 | Henrik Grubbström (Grubba) | | cache_clear_deltas();
|
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;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | |
#ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if (h[0] != bg_process_queue &&
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | |
|
f931d7 | 2008-09-29 | Martin Stjernholm | | (monitor = slow_req_monitor) && slow_req_timeout > 0.0) {
call_out = monitor->call_out (dump_slow_req, slow_req_timeout,
this_thread(), slow_req_timeout);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | h[0](@h[1]);
|
f931d7 | 2008-09-29 | Martin Stjernholm | | monitor->remove_call_out (call_out);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
else
#endif
h[0](@h[1]);
|
45cae3 | 1998-03-06 | Henrik Grubbström (Grubba) | | 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--;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if (call_out) monitor->remove_call_out (call_out);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #endif
|
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;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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 | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int num_hold_messages;
protected 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;
}
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected Thread.MutexKey backend_block_lock;
|
3bc3a7 | 2001-02-22 | Martin Stjernholm | |
|
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 )
{
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int async_called;
|
50b58b | 2001-01-31 | Per Hedbor | |
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
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected Thread.Queue bg_queue = Thread.Queue();
protected int bg_process_running;
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected constant bg_time_buffer_max = 30;
protected constant bg_time_buffer_min = 0;
protected int bg_last_busy = 0;
|
8f6382 | 2001-02-27 | Martin Stjernholm | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void bg_process_queue()
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
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);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | Pike.Backend monitor;
mixed call_out;
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #endif
|
76ae18 | 2001-02-23 | Martin Stjernholm | | if (mixed err = catch {
|
d47483 | 2008-10-26 | Martin Stjernholm | | while (bg_queue->size() && !shutdown_started) {
|
164a58 | 2003-04-14 | Martin Stjernholm | |
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());
#endif
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | |
float task_vtime, task_rtime;
#ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if ((monitor = slow_req_monitor) && slow_req_timeout > 0.0) {
call_out = monitor->call_out (dump_slow_req, slow_req_timeout,
this_thread(), slow_req_timeout);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | int start_hrtime = gethrtime (1);
task_vtime = gauge {
if (task[0])
task[0] (@task[1]);
};
task_rtime = (gethrtime (1) - start_hrtime) / 1e9;
|
f931d7 | 2008-09-29 | Martin Stjernholm | | monitor->remove_call_out (call_out);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | }
|
4905ea | 2008-09-30 | Martin Stjernholm | | else
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #endif
|
4905ea | 2008-09-30 | Martin Stjernholm | | {
int start_hrtime = gethrtime (1);
task_vtime = gauge {
if (task[0])
task[0] (@task[1]);
};
task_rtime = (gethrtime (1) - start_hrtime) / 1e9;
}
|
f154ad | 2008-05-13 | Martin Stjernholm | |
if (task_rtime > 60.0)
report_warning ("Warning: Background job took more than one minute "
"(%g s real time and %g s cpu time):\n"
" %s (%s)\n%s",
task_rtime, task_vtime,
functionp (task[0]) ?
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]),
map (task[1], lambda (mixed arg)
{return sprintf ("%O", arg);}) * ", ",
bg_queue->size() ?
(bg_queue->size() > 1 ?
" " + bg_queue->size() + " more jobs in the "
"background queue were delayed.\n" :
" 1 more job in the background queue was delayed.\n"):
"");
#ifdef DEBUG_BACKGROUND_RUN
else
report_debug ("background_run done, "
"took %g ms cpu time and %g ms real time\n",
task_vtime * 1000, task_rtime * 1000);
|
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 | | }
}) {
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #ifndef NO_SLOW_REQ_BT
|
f931d7 | 2008-09-29 | Martin Stjernholm | | if (call_out) monitor->remove_call_out (call_out);
|
b1b4e4 | 2008-09-22 | Martin Stjernholm | | #endif
|
76ae18 | 2001-02-23 | Martin Stjernholm | | bg_process_running = 0;
handle (bg_process_queue);
throw (err);
}
bg_process_running = 0;
}
#endif
|
63a857 | 2006-11-14 | Martin Stjernholm | | mixed background_run (int|float delay, function func, mixed... args)
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
|
76e01e | 2008-09-11 | Martin Stjernholm | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
|
76e01e | 2008-09-11 | Martin Stjernholm | |
|
63a857 | 2006-11-14 | Martin Stjernholm | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
|
24f964 | 2007-05-03 | 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)
|
63a857 | 2006-11-14 | Martin Stjernholm | | return 0;
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
|
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);
};
|
63a857 | 2006-11-14 | Martin Stjernholm | | mixed res;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | if (delay)
|
63a857 | 2006-11-14 | Martin Stjernholm | | res = call_out (enqueue, delay);
|
76ae18 | 2001-02-23 | Martin Stjernholm | | else
enqueue();
|
6e2e5d | 2003-01-20 | Martin Stjernholm | | enqueue = 0;
|
63a857 | 2006-11-14 | Martin Stjernholm | | return res;
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #else
|
63a857 | 2006-11-14 | Martin Stjernholm | | return call_out (func, delay, @args);
|
76ae18 | 2001-02-23 | Martin Stjernholm | | #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;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void repeat (function func, mixed args)
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
|
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
|
b9e5cb | 2007-10-11 | Henrik Grubbström (Grubba) | | if (stopping || (self_refs <= 4) || !func) return;
mixed err = catch {
func (@args);
};
if (err) {
catch {
|
fe07f5 | 2008-01-10 | Jonas Wallden | | report_error(LOC_M(66, "Uncaught error in background process:") +
|
b9e5cb | 2007-10-11 | Henrik Grubbström (Grubba) | | "%s\n", describe_backtrace(err));
};
}
|
76ae18 | 2001-02-23 | Martin Stjernholm | | background_run (period, repeat, func, args);
}
|
d35d5f | 2001-06-13 | Jonas Wallden | |
|
63a857 | 2006-11-14 | Martin Stjernholm | |
|
d35d5f | 2001-06-13 | Jonas Wallden | | void set_period (int|float period_)
{
period = period_;
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | |
|
76ae18 | 2001-02-23 | Martin Stjernholm | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void create (int|float period_, function func, mixed... args)
|
76ae18 | 2001-02-23 | Martin Stjernholm | | {
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
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping(string:int(0..1)) host_is_local_cache = ([]);
|
cd86f3 | 2003-10-22 | Henrik Grubbström (Grubba) | |
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;
}
|
d02e95 | 2008-11-04 | Martin Stjernholm | | array(Protocol|mapping(string:mixed)) find_port_for_url (
Standards.URI url, void|Configuration only_this_conf)
|
ad8cfd | 2009-01-10 | Martin Stjernholm | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
|
6dcf35 | 2002-09-20 | Anders Johansson | | {
|
4d1271 | 2009-01-16 | Martin Stjernholm | |
string host = url->host;
|
8410c2 | 2009-01-17 | Martin Stjernholm | | if (has_value (host, ":"))
host = "[" + (Protocols.IPv6.normalize_addr_basic (host) || host) + "]";
|
4d1271 | 2009-01-16 | Martin Stjernholm | | string url_with_port = sprintf ("%s://%s:%d%s", url->scheme, 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);
|
d02e95 | 2008-11-04 | Martin Stjernholm | | foreach (urls; string u; mapping(string:mixed) q)
|
6dcf35 | 2002-09-20 | Anders Johansson | | {
|
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");
|
d02e95 | 2008-11-04 | Martin Stjernholm | | if (Protocol p = q->port)
if (mapping(string:mixed) url_data =
|
ad8cfd | 2009-01-10 | Martin Stjernholm | | p->find_url_data_for_url (url_with_port, 0, 0))
|
d02e95 | 2008-11-04 | Martin Stjernholm | | {
|
0bb7d3 | 2008-12-03 | Jonas Wallden | | Configuration c = url_data->conf;
URL2CONF_MSG("Found config: %O\n", url_data->conf);
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
if ((only_this_conf && (c != only_this_conf)) ||
|
dc8928 | 2008-12-11 | Jonas Wallden | | (sscanf (u, "%*s://%*[^*?]%*c") == 3 &&
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
(!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)));
c = 0;
continue;
}
URL2CONF_MSG("Result: %O\n", c);
return ({p, url_data});
|
9ec100 | 2002-10-01 | Anders Johansson | | }
}
|
6dcf35 | 2002-09-20 | Anders Johansson | | }
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
return ({0, 0});
}
Configuration find_configuration_for_url(Standards.URI url,
void|Configuration only_this_conf,
void|array(Protocol) return_port)
{
[Protocol port_obj, mapping(string:mixed) url_data] =
find_port_for_url (url, only_this_conf);
|
8bb1f6 | 2005-05-31 | Jonas Wallden | | if (return_port)
|
d02e95 | 2008-11-04 | Martin Stjernholm | | return_port[0] = port_obj;
return url_data && url_data->conf;
|
6dcf35 | 2002-09-20 | Anders Johansson | | }
|
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;
|
fe6b38 | 2006-09-29 | Jonas Wallden | | if ((prot == "HTTP" && uri->port != 80) ||
(prot == "HTTPS" && uri->port != 443))
misc->host += ":" + uri->port;
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | 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";
|
d02e95 | 2008-11-04 | Martin Stjernholm | | [port_obj, mapping(string:mixed) url_data] = find_port_for_url (uri, 0);
if (url_data) {
conf = url_data->conf;
if (!conf->inited) conf->enable_all_modules();
|
a261b5 | 2008-11-04 | Martin Stjernholm | | if (string config_path = url_data->path)
adjust_for_config_path (config_path);
|
d02e95 | 2008-11-04 | Martin Stjernholm | | }
|
8cbc5f | 2002-09-03 | Martin Stjernholm | | return set_path( raw_url );
|
7ead5a | 2001-08-15 | Per Hedbor | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected string _sprintf()
|
7ead5a | 2001-08-15 | Per Hedbor | | {
return sprintf("RequestID(conf=%O; not_query=%O)", conf, not_query );
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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 = ([]);
|
f6bf15 | 2005-12-07 | Henrik Grubbström (Grubba) | | cookies = CookieJar();
|
4c04e5 | 2000-07-25 | Marcus Comstedt | | 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 | | {
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected Stdio.Port port_obj;
|
722c9e | 2001-11-07 | Henrik Grubbström (Grubba) | |
|
934b3f | 2000-02-04 | Per Hedbor | | inherit "basic_defvar";
|
3a5315 | 2008-09-17 | Martin Stjernholm | |
|
abc59a | 2000-08-23 | Per Hedbor | | int bound;
|
3a5315 | 2008-09-17 | Martin Stjernholm | |
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
5773f6 | 2000-08-27 | Martin Stjernholm | | string path;
|
c5e096 | 1999-10-04 | Per Hedbor | | constant name = "unknown";
|
ad8cfd | 2009-01-10 | Martin Stjernholm | |
|
c5e096 | 1999-10-04 | Per Hedbor | | 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 | |
|
07fe26 | 2005-11-25 | Henrik Grubbström (Grubba) | | string url_prefix = name + "://";
|
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;
|
c80d9f | 2009-01-11 | Stephen R. van den Berg | |
|
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 | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | mapping(string:mapping(string:mixed)) urls = ([]);
|
a6e4a1 | 2000-07-09 | Per Hedbor | |
|
1bcd22 | 2007-09-06 | Henrik Grubbström (Grubba) | |
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | mapping(Configuration:mapping(string:mixed)) conf_data = ([]);
|
ea65f7 | 2001-07-21 | Martin Stjernholm | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | void ref(string name, mapping(string:mixed) 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++;
|
71e412 | 2009-01-11 | Martin Stjernholm | | mu = 0;
|
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);
|
c80d9f | 2009-01-11 | Stephen R. van den Berg | | if (!path) {
array(string) paths = Array.uniq (values (urls)->path);
if (sizeof (paths) == 1) path = paths[0];
}
|
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;
|
d6adf4 | 2005-11-18 | Henrik Grubbström (Grubba) | | if (open_ports[name]) {
if (open_ports[name][ip]) {
m_delete(open_ports[name][ip], port);
|
d78720 | 2005-11-30 | Henrik Grubbström (Grubba) | | if(!sizeof(open_ports[name][ip])) {
if (ip && ip != "::")
m_delete(open_ports[name], ip);
}
}
if (sizeof(open_ports[name]) <= 2) {
int empty = 1;
foreach(open_ports[name]; string ip; mapping m) {
if (sizeof(m)) {
empty = 0;
break;
}
}
if (empty)
m_delete(open_ports, name);
|
d6adf4 | 2005-11-18 | Henrik Grubbström (Grubba) | | }
}
|
5d3355 | 2009-01-10 | Martin Stjernholm | | any_port = 0;
|
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 | | }
|
d02e95 | 2008-11-04 | Martin Stjernholm | | mapping(string:mixed) mu;
|
851483 | 2000-11-27 | Per Hedbor | | string rrhf;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void got_connection()
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
55f927 | 2006-12-21 | Henrik Grubbström (Grubba) | | Stdio.File q;
while( q = accept() )
|
1550aa | 2000-08-12 | Per Hedbor | | {
|
03b7a2 | 2007-09-10 | Henrik Grubbström (Grubba) | | if( !requesthandler && rrhf )
|
851483 | 2000-11-27 | Per Hedbor | | {
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)
{
|
c80d9f | 2009-01-11 | Stephen R. van den Berg | | mu = get_iterator(urls)->value();
|
5b5c80 | 2008-09-29 | Martin Stjernholm | | if(!(c=mu->conf)->inited ) {
handle (lambda () {
c->enable_all_modules();
call_out (requesthandler, 0, q, this, c);
});
return;
}
|
1f4a6c | 2000-08-28 | Per Hedbor | | } else
c = mu->conf;
|
1550aa | 2000-08-12 | Per Hedbor | | }
requesthandler( q, this_object(), c );
}
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | }
|
5d3355 | 2009-01-10 | Martin Stjernholm | | private Protocol any_port;
|
347c72 | 2000-08-31 | Per Hedbor | |
|
ad8cfd | 2009-01-10 | Martin Stjernholm | | mapping(string:mixed) find_url_data_for_url (string url, int no_default,
RequestID id)
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | {
|
c80d9f | 2009-01-11 | Stephen R. van den Berg | | if( refs == 1 )
|
4c8777 | 2000-08-11 | Per Hedbor | | {
|
c80d9f | 2009-01-11 | Stephen R. van den Berg | | if (!no_default) {
if(!mu) mu=get_iterator(urls)->value();
URL2CONF_MSG ("%O %O Only one configuration: %O\n",
this, url, mu->conf);
return mu;
}
} else if (!refs) {
|
d02e95 | 2008-11-04 | Martin Stjernholm | | URL2CONF_MSG("%O %O No active URLS!\n", this, url);
|
3d18ba | 2001-12-19 | Henrik Grubbström (Grubba) | | return 0;
|
4c8777 | 2000-08-11 | Per Hedbor | | }
|
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 ) )
{
|
d02e95 | 2008-11-04 | Martin Stjernholm | | URL2CONF_MSG ("%O %O sorted_urls: %O\n", this, url, urls[in]->conf);
return urls[in];
|
ddefa6 | 1999-10-04 | Marcus Comstedt | | }
}
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | if( no_default ) {
|
d02e95 | 2008-11-04 | Martin Stjernholm | | URL2CONF_MSG ("%O %O no default\n", this, url);
|
8fb517 | 2000-05-27 | Per Hedbor | | return 0;
|
ea65f7 | 2001-07-21 | Martin Stjernholm | | }
|
ad8cfd | 2009-01-10 | Martin Stjernholm | |
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
347c72 | 2000-08-31 | Per Hedbor | |
|
5d3355 | 2009-01-10 | Martin Stjernholm | | if (!any_port)
any_port = open_ports[ name ][ 0 ][ port ];
if (any_port && any_port != this)
if (mapping(string:mixed) u =
any_port->find_url_data_for_url (url, 1, id)) {
URL2CONF_MSG ("%O %O found on ANY port: %O\n", this, url, u->conf);
if (id) {
id->misc->defaulted_conf = 1;
id->port_obj = any_port;
}
|
d02e95 | 2008-11-04 | Martin Stjernholm | | return u;
}
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | mapping(Configuration:int(1..1)) choices = ([]);
|
d09399 | 2000-09-25 | Per Hedbor | | foreach( configurations, Configuration c )
|
8fb517 | 2000-05-27 | Per Hedbor | | if( c->query( "default_server" ) )
|
d02e95 | 2008-11-04 | Martin Stjernholm | | choices[c] = 1;
|
8fb517 | 2000-05-27 | Per Hedbor | |
if( sizeof( choices ) )
|
7120b8 | 2000-03-27 | Per Hedbor | | {
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
foreach (urls;; mapping cc)
|
347c72 | 2000-08-31 | Per Hedbor | | if( choices[ cc->conf ] )
|
8fb517 | 2000-05-27 | Per Hedbor | | {
|
d02e95 | 2008-11-04 | Martin Stjernholm | | URL2CONF_MSG ("%O %O conf in choices: %O\n", this, url, cc->conf);
|
ad8cfd | 2009-01-10 | Martin Stjernholm | | if (id) id->misc->defaulted_conf = 2;
|
d02e95 | 2008-11-04 | Martin Stjernholm | | return cc;
|
8fb517 | 2000-05-27 | Per Hedbor | | }
|
d02e95 | 2008-11-04 | Martin Stjernholm | | }
|
347c72 | 2000-08-31 | Per Hedbor | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | return 0;
}
|
347c72 | 2000-08-31 | Per Hedbor | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | Configuration find_configuration_for_url( string url, RequestID id )
{
|
ad8cfd | 2009-01-10 | Martin Stjernholm | | mapping(string:mixed) url_data = find_url_data_for_url (url, 0, id);
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
if (!url_data) {
foreach (configurations, Configuration c)
if (c->query ("default_server")) {
URL2CONF_MSG ("%O %O any default server: %O\n", this, url, c);
|
ad8cfd | 2009-01-10 | Martin Stjernholm | | if (id) id->misc->defaulted_conf = 3;
|
d02e95 | 2008-11-04 | Martin Stjernholm | | if(!c->inited)
c->enable_all_modules();
return c;
}
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | |
|
ad8cfd | 2009-01-10 | Martin Stjernholm | |
url_data = urls[sorted_urls[-1]];
if (id) {
id->misc->defaulted_conf = 4;
id->misc->defaulted=1;
}
URL2CONF_MSG ("%O %O last in sorted_urls: %O\n", this, url,
|
d02e95 | 2008-11-04 | Martin Stjernholm | | url_data->conf);
}
|
8fb517 | 2000-05-27 | Per Hedbor | |
|
5d3355 | 2009-01-10 | Martin Stjernholm | |
|
d02e95 | 2008-11-04 | Martin Stjernholm | | string config_path = url_data->path;
if (config_path && id && id->adjust_for_config_path)
id->adjust_for_config_path (config_path);
Configuration c = url_data->conf;
if(!c->inited)
c->enable_all_modules();
|
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) | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int retries;
protected void bind (void|int ignore_eaddrinuse)
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | {
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 */
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | #if constant(System.EADDRINUSE)
|
3a5315 | 2008-09-17 | Martin Stjernholm | | if (port_obj->errno() == System.EADDRINUSE) {
if (ignore_eaddrinuse) {
bound = -1;
return;
}
if (retries++ < 10) {
|
24f964 | 2007-05-03 | Martin Stjernholm | |
report_error(LOC_M(6, "Failed to bind %s (%s)")+"\n",
get_url(), strerror(port_obj->errno()));
report_notice(LOC_M(62, "Attempt %d. Retrying in 1 minute.")+"\n",
retries);
call_out(bind, 60);
}
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | }
|
24f964 | 2007-05-03 | Martin Stjernholm | | else
|
3a5315 | 2008-09-17 | Martin Stjernholm | | #endif /* constant(System.EADDRINUSE) */
|
24f964 | 2007-05-03 | Martin Stjernholm | | {
report_error(LOC_M(6, "Failed to bind %s (%s)")+"\n",
get_url(), strerror(port_obj->errno()));
#if 0
werror (describe_backtrace (backtrace()));
#endif
}
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | }
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | | string canonical_ip(string i)
{
|
157e6e | 2005-03-07 | Martin Stjernholm | | if (!i) return 0;
|
8410c2 | 2009-01-17 | Martin Stjernholm | | if (has_value(i, ":"))
return Protocols.IPv6.normalize_addr_short (i);
else {
|
d55e64 | 2005-03-02 | Henrik Grubbström (Grubba) | |
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));
}
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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();
|
03b7a2 | 2007-09-10 | Henrik Grubbström (Grubba) | | if (sizeof(requesthandlerfile)) {
if( file_stat( "../local/"+requesthandlerfile ) )
rrhf = "../local/"+requesthandlerfile;
else
rrhf = requesthandlerfile;
DDUMP( rrhf );
|
851483 | 2000-11-27 | Per Hedbor | | #ifdef DEBUG
|
03b7a2 | 2007-09-10 | Henrik Grubbström (Grubba) | | if( !requesthandler )
requesthandler = (program)(rrhf);
|
851483 | 2000-11-27 | Per Hedbor | | #endif
|
03b7a2 | 2007-09-10 | Henrik Grubbström (Grubba) | | }
|
044f14 | 2003-11-05 | Henrik Grubbström (Grubba) | | bound = 0;
port_obj = 0;
retries = 0;
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void create( int pn, string i, void|int ignore_eaddrinuse )
|
fe1c13 | 2005-05-25 | Martin Stjernholm | |
{
setup (pn, i);
|
24f964 | 2007-05-03 | Martin Stjernholm | | bind (ignore_eaddrinuse);
|
c5e096 | 1999-10-04 | Per Hedbor | | }
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void cert_err_unbind()
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | {
|
3a5315 | 2008-09-17 | Martin Stjernholm | | if (bound > 0) {
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | 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)
|
fc4039 | 2008-08-15 | Martin Stjernholm | | void certificates_changed(Variable.Variable|void ignored,
|
24f964 | 2007-05-03 | Martin Stjernholm | | void|int ignore_eaddrinuse)
|
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 = ({});
|
fc4039 | 2008-08-15 | Martin Stjernholm | | Variable.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(),
|
eabb19 | 2006-01-25 | Anders Johansson | | LOC_M(63,"No certificates found.\n"));
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | cert_err_unbind();
cert_failure = 1;
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | return;
}
|
81f8af | 1999-12-20 | Martin Nilsson | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | Variable.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)
{
ctx->short_rsa = Crypto.RSA()->generate_key(512, ctx->random);
|
fc4039 | 2008-08-15 | Martin Stjernholm | |
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | }
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) {
|
24f964 | 2007-05-03 | Martin Stjernholm | | bind (ignore_eaddrinuse);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | if (old_cert_failure && bound)
|
eabb19 | 2006-01-25 | Anders Johansson | | report_notice (LOC_M(64, "TLS port %s opened.\n"), get_url());
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | }
|
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());
}
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | SSL.sslfile accept()
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | {
Stdio.File q = ::accept();
if (q)
|
fc4039 | 2008-08-15 | Martin Stjernholm | | return SSL.sslfile (q, ctx);
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | return 0;
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void bind (void|int ignore_eaddrinuse)
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | {
if (!ctx->certificates) return;
|
24f964 | 2007-05-03 | Martin Stjernholm | | ::bind (ignore_eaddrinuse);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | }
|
24f964 | 2007-05-03 | Martin Stjernholm | | void create(int pn, string i, void|int ignore_eaddrinuse)
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | | {
ctx->random = Crypto.Random.random_string;
set_up_ssl_variables( this_object() );
|
fe1c13 | 2005-05-25 | Martin Stjernholm | | ::setup(pn, i);
|
85fbbc | 2004-08-19 | Henrik Grubbström (Grubba) | |
|
24f964 | 2007-05-03 | Martin Stjernholm | | certificates_changed (0, ignore_eaddrinuse);
|
fe1c13 | 2005-05-25 | Martin Stjernholm | |
|
58258e | 2006-05-16 | Henrik Grubbström (Grubba) | |
|
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) | |
|
3a5315 | 2008-09-17 | Martin Stjernholm | | mapping(string:program) 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;
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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) | |
|
3a5315 | 2008-09-17 | Martin Stjernholm | | mapping(string:program) protocols;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | |
mapping(string:mapping(string:mapping(int:Protocol))) open_ports = ([ ]);
|
3c81c0 | 2008-12-11 | Henrik Grubbström (Grubba) | | mapping(string:mapping(string:Configuration|Protocol|string)) 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 | | }
|
db4db5 | 2009-01-21 | Martin Stjernholm | | string normalize_url(string url, void|int port_match_form)
|
c5e096 | 1999-10-04 | Per Hedbor | | {
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | if (!sizeof (url - " " - "\t")) return "";
|
21182a | 2001-10-05 | Per Hedbor | | Standards.URI ui = Standards.URI(url);
|
db4db5 | 2009-01-21 | Martin Stjernholm | | string host = ui->host;
if (lower_case (host) == "any" || host == "::")
host = "*";
|
1f6b0c | 2008-12-23 | Martin Stjernholm | | else
|
db4db5 | 2009-01-21 | Martin Stjernholm | | host = lower_case(Standards.IDNA.zone_to_ascii (host));
if (has_value (host, ":"))
if (string h = port_match_form ?
Protocols.IPv6.normalize_addr_basic (host) :
Protocols.IPv6.normalize_addr_short (host)) {
ui->host = h;
host = "[" + h + "]";
}
|
dc8928 | 2008-12-11 | Jonas Wallden | | string protocol = ui->scheme;
|
db4db5 | 2009-01-21 | Martin Stjernholm | | if (host == "" || !protocols[protocol])
|
dc8928 | 2008-12-11 | Jonas Wallden | | return "";
|
db4db5 | 2009-01-21 | Martin Stjernholm | |
if (port_match_form) {
int port = ui->port || protocols[protocol]->default_port;
string path = ui->path;
if (path) {
if (has_suffix(path, "/"))
path = path[..<1];
}
else
path = "";
return sprintf ("%s://%s:%d%s/", protocol, host, port,
path);
}
else {
ui->fragment = 0;
return (string) ui;
}
|
38c489 | 2002-01-11 | Henrik Grubbström (Grubba) | | }
void unregister_url(string url, Configuration conf)
{
string ourl = url;
|
8817ca | 2009-01-23 | Martin Stjernholm | | if (!sizeof(url = normalize_url(url, 1))) return;
|
bc5c2a | 2000-08-23 | Per Hedbor | |
|
8817ca | 2009-01-23 | Martin Stjernholm | | report_debug ("Unregister %s%s.\n", normalize_url (ourl),
conf ? sprintf (" for %O", conf->query_name()) : "");
|
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;
|
1e3cd5 | 2000-02-02 | Martin Stjernholm | | if (!sizeof (url - " " - "\t")) return 1;
|
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;
}
|
db4db5 | 2009-01-21 | Martin Stjernholm | |
|
21182a | 2001-10-05 | Per Hedbor | | 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",
|
dc8928 | 2008-12-11 | Jonas Wallden | | (string) ui );
|
21182a | 2001-10-05 | Per Hedbor | | return 0;
}
|
1f6b0c | 2008-12-23 | Martin Stjernholm | |
|
db4db5 | 2009-01-21 | Martin Stjernholm | | url = normalize_url (url, 1);
ui = Standards.URI (url);
string protocol = ui->scheme;
string host = ui->host;
|
4d1271 | 2009-01-16 | Martin Stjernholm | | if (host == "" || !protocols[protocol]) {
|
db4db5 | 2009-01-21 | Martin Stjernholm | | report_error(LOC_M(19,"Bad URL %O for server `%s'")+"\n",
ourl, conf->query_name());
|
228fea | 2000-02-15 | Leif Stensson | | }
|
b8fd5c | 2000-09-28 | Per Hedbor | |
|
db4db5 | 2009-01-21 | Martin Stjernholm | | int port = ui->port || protocols[protocol]->default_port;
|
4d1271 | 2009-01-16 | Martin Stjernholm | |
|
db4db5 | 2009-01-21 | Martin Stjernholm | | string path = ui->path;
if (has_suffix(path, "/"))
path = path[..<1];
if (path == "") path = 0;
|
c5e096 | 1999-10-04 | Per Hedbor | |
|
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 | | }
|
3a5315 | 2008-09-17 | Martin Stjernholm | | program prot;
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | |
|
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;
}
|
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;
|
24f964 | 2007-05-03 | Martin Stjernholm | | int opened_ipv4_any_port;
|
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 ] )
{
|
a2ec27 | 2008-09-20 | Martin Stjernholm | | if (!required_host) opened_ipv4_any_port = 1;
|
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];
|
96af3e | 2009-03-23 | Henrik Grubbström (Grubba) | | if (urls[ourl]->ports) {
urls[ourl]->ports += ({ m[required_host][port] });
} else {
urls[ourl]->ports = ({ m[required_host][port] });
}
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | continue;
}
if( !m[ required_host ] )
m[ required_host ] = ([ ]);
|
3a5315 | 2008-09-17 | Martin Stjernholm | | if (mixed err = catch {
|
24f964 | 2007-05-03 | Martin Stjernholm | | m[ required_host ][ port ] =
prot( port, required_host,
required_host == "::" && opened_ipv4_any_port);
|
41a5c0 | 2003-10-22 | Henrik Grubbström (Grubba) | | }) {
|
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 | |
|
24f964 | 2007-05-03 | Martin Stjernholm | | if (!required_host) opened_ipv4_any_port = 1;
|
3a5315 | 2008-09-17 | Martin Stjernholm | | Protocol prot_obj = m[required_host][port];
if( !prot_obj )
|
dd7e66 | 1999-10-09 | Henrik Grubbström (Grubba) | | {
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 | |
|
3a5315 | 2008-09-17 | Martin Stjernholm | | if (prot_obj->bound == -1) {
m_delete (m[required_host], port);
continue;
}
|
abc59a | 2000-08-23 | Per Hedbor | |
|
3a5315 | 2008-09-17 | Martin Stjernholm | | urls[ url ]->port = prot_obj;
urls[ ourl ]->port = prot_obj;
|
96af3e | 2009-03-23 | Henrik Grubbström (Grubba) | | if (urls[ourl]->ports) {
urls[ourl]->ports += ({ prot_obj });
} else {
urls[ourl]->ports = ({ prot_obj });
}
|
3a5315 | 2008-09-17 | Martin Stjernholm | | prot_obj->ref(url, urls[url]);
|
03aa49 | 2000-08-23 | Per Hedbor | |
|
3a5315 | 2008-09-17 | Martin Stjernholm | | if( !prot_obj->bound )
|
03aa49 | 2000-08-23 | Per Hedbor | | 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();
|
1f6b0c | 2008-12-23 | Martin Stjernholm | |
|
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 | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int last_hrtime = gethrtime(1)/100;
protected int clock_sequence = random(0x4000);
protected string hex_mac_address =
String.string2hex(Crypto.Random.random_string (6)|
"\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()
{
|
4e3207 | 2009-01-09 | Stephen R. van den Berg | | return String.string2hex(Crypto.MD5.hash(query("server_salt") + start_time
+ "|" + (unique_id_counter++) + "|" + time(1)));
|
38b81e | 2001-01-06 | Martin Nilsson | | }
|
c8ee71 | 2000-09-09 | Andreas Lange | |
|
dbfe9d | 2000-04-13 | Per Hedbor | | #ifndef __NT__
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected int abs_started;
protected int handlers_alive;
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void low_engage_abs()
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | {
report_debug("**** %s: ABS exiting roxen!\n\n",
ctime(time()) - "\n");
_exit(1);
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void engage_abs(int n)
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | {
if (!query("abs_engage")) {
abs_started = 0;
report_debug("Anti-Block System Disabled.\n");
return;
}
report_debug("**** %s: ABS engaged!\n"
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | "Waited more than %d minute(s).\n",
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | ctime(time()) - "\n",
query("abs_timeout"));
signal(signum("SIGALRM"), low_engage_abs);
int t = alarm(20);
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | #ifdef THREADS
report_debug("Handler queue:\n");
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch {
|
9fe96a | 2007-08-14 | Henrik Grubbström (Grubba) | | array(mixed) queue = handle_queue->buffer[handle_queue->r_ptr..];
|
d60119 | 2007-08-14 | Henrik Grubbström (Grubba) | | foreach(queue, mixed v) {
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | if (!v) continue;
if (!arrayp(v)) {
report_debug(" *** Strange entry: %O ***\n", v);
} else {
|
9fe96a | 2007-08-14 | Henrik Grubbström (Grubba) | | report_debug(" %{%O, %}\n", v/({}));
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | }
}
|
d307c7 | 2008-08-06 | Martin Stjernholm | | })
werror (describe_backtrace (err));
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | #endif
report_debug("Trying to dump backlog: \n");
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch {
describe_all_threads();
})
werror (describe_backtrace (err));
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | low_engage_abs();
}
|
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;
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | handlers_alive = time();
|
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 | |
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | signal(signum("SIGALRM"), engage_abs);
|
e0e50e | 2001-11-23 | Anders Johansson | | int t = alarm (60*query("abs_timeout")+20);
|
679c9e | 2006-11-30 | Henrik Grubbström (Grubba) | | if ((time(1) - handlers_alive) > 60*query("abs_timeout")) {
report_debug("**** %s: ABS: Handlers are dead!\n",
ctime(time()) - "\n");
engage_abs(0);
}
|
082b5e | 2007-08-14 | Henrik Grubbström (Grubba) | | handle(lambda() { handlers_alive = time(); });
|
edc9af | 1998-07-11 | David Hedbor | | }
|
dbfe9d | 2000-04-13 | Per Hedbor | | #endif
|
edc9af | 1998-07-11 | David Hedbor | |
|
2cb514 | 2006-08-21 | Henrik Grubbström (Grubba) | | #if constant(ROXEN_MYSQL_SUPPORTS_UNICODE)
#define MYSQL__BINARY "_binary"
#else
#define MYSQL__BINARY ""
#endif
|
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 | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping meta_cache_insert( string i, mapping what )
|
2ff846 | 1999-09-02 | Per Hedbor | | {
|
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 | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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 | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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 | |
|
45063f | 2009-03-20 | Henrik Grubbström (Grubba) | | id->cache_status["icachedraw"] = 1;
|
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 | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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+
|
d700c4 | 2006-08-21 | Henrik Grubbström (Grubba) | | " (id,size,atime,meta,data) VALUES"
|
2cb514 | 2006-08-21 | Henrik Grubbström (Grubba) | | " (%s,%d,UNIX_TIMESTAMP()," MYSQL__BINARY "%s," MYSQL__BINARY "%s)",
|
2af730 | 2004-02-05 | Anders Johansson | | id, strlen(data)+strlen(meta_data), meta_data, data );
|
9b0aaa | 2006-08-21 | Henrik Grubbström (Grubba) | | #ifdef ARG_CACHE_DEBUG
array(mapping(string:string)) q =
QUERY("SELECT meta, data FROM " + name +
" WHERE id = %s", id);
if (!q || sizeof(q) != 1) {
werror("Unexpected result size: %d\n",
q && sizeof(q));
} else {
if (q[0]->meta != meta_data) {
werror("Meta data differs: %O != %O\n",
meta_data, q[0]->meta);
}
if (q[0]->data != data) {
werror("Data differs: %O != %O\n",
data, q[0]->data);
}
}
#endif
|
69a869 | 1999-05-18 | Per Hedbor | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping restore_meta( string id, RequestID rid )
|
69a869 | 1999-05-18 | Per Hedbor | | {
|
796ebc | 2007-01-10 | Martin Jonsson | | if( array item = meta_cache[ id ] )
|
e7ac49 | 2003-04-06 | Anders Johansson | | {
|
796ebc | 2007-01-10 | Martin Jonsson | | item[ 1 ] = time(1);
return item[ 0 ];
|
e7ac49 | 2003-04-06 | Anders Johansson | | }
|
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 | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void sync_meta()
|
e7ac49 | 2003-04-06 | Anders Johansson | | {
|
1e04a0 | 2006-11-14 | Anders Johansson | | foreach(meta_cache; string id; array value) {
if (value[1])
|
e7ac49 | 2003-04-06 | Anders Johansson | | QUERY("UPDATE "+name+" SET atime=%d WHERE id=%s",
|
1e04a0 | 2006-11-14 | Anders Johansson | | value[1], id);
|
e7ac49 | 2003-04-06 | Anders Johansson | | }
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 | |
|
2f0ae1 | 2007-05-10 | Martin Stjernholm | | #if 0
|
354801 | 2001-08-10 | Per Hedbor | | if( num )
catch
{
|
03b174 | 2007-01-29 | Jonas Wallden | | #ifdef DEBUG
|
a4a5fc | 2007-01-30 | Jonas Wallden | | report_debug("Optimizing database ... ", name);
|
03b174 | 2007-01-29 | Jonas Wallden | | #endif
|
354801 | 2001-08-10 | Per Hedbor | | QUERY( "OPTIMIZE TABLE "+name );
};
|
2f0ae1 | 2007-05-10 | Martin Stjernholm | | #endif
|
29fac1 | 2001-01-04 | Martin Nilsson | |
|
354801 | 2001-08-10 | Per Hedbor | | #ifdef DEBUG
|
a4a5fc | 2007-01-30 | Jonas Wallden | | 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 | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping(string:mapping) rst_cache = ([ ]);
protected mapping(string:string) uid_cache = ([ ]);
|
4afcd4 | 2001-08-09 | Per Hedbor | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected 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");
}
|
45063f | 2009-03-20 | Henrik Grubbström (Grubba) | | if( rst_cache[ id ] ) {
rid->cache_status["icacheram"] = 1;
|
9fcbed | 2001-01-20 | Per Hedbor | | return rst_cache[ id ] + ([]);
|
45063f | 2009-03-20 | Henrik Grubbström (Grubba) | | }
|
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;
|
d307c7 | 2008-08-06 | Martin Stjernholm | | if (mixed err = catch( m = decode_value( q[0]->meta ) ))
report_debug ("Failed to decode meta mapping for id %O in %s: %s",
id, name, describe_error (err));
|
4afcd4 | 2001-08-09 | Per Hedbor | | if( !m ) return 0;
|
9fcbed | 2001-01-20 | Per Hedbor | |
|
45063f | 2009-03-20 | Henrik Grubbström (Grubba) | | rid->cache_status["icachedisk"] = 1;
|
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) | |
|
ce0e28 | 2006-11-14 | Anders Johansson | |
if(arrayp(err) && sizeof(err) && stringp(err[0]))
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | {
|
ce0e28 | 2006-11-14 | Anders Johansson | | if (sscanf(err[0], "Requesting unknown key %s\n",
string message) == 1)
{
report_debug("Requesting unknown key %s %O from %O\n",
message,
id->not_query,
(sizeof(id->referer)?id->referer[0]:"unknown page"));
return 0;
}
if (sscanf(err[0], "Failed to load specified image [\"%s\"]\n",
string message) == 1)
{
report_debug("Failed to load specified image %O from %O - referrer %O\n",
message,
id->not_query,
(sizeof(id->referer)?id->referer[0]:"unknown page"));
return 0;
}
|
2fea13 | 2004-02-09 | Marcus Wellhardh | | }
|
ce0e28 | 2006-11-14 | Anders Johansson | | 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 | |
|
5f3e08 | 2009-02-19 | Jonas Wallden | |
|
5f2c2f | 2003-11-25 | Anders Johansson | | RAISE_CACHE(INITIAL_CACHEABLE);
|
5f3e08 | 2009-02-19 | Jonas Wallden | |
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) {
|
464a08 | 2006-11-16 | Martin Stjernholm | |
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | foreach(ci/"$", string key) {
|
254e97 | 2006-03-15 | Marcus Wellhardh | | #if ARGCACHE_DEBUG
|
9ea9b7 | 2001-11-27 | Henrik Grubbström (Grubba) | | werror("Request for id %O from prefetch crawler.\n", key);
|
254e97 | 2006-03-15 | Marcus Wellhardh | | #endif /* ARGCACHE_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;
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void setup_tables()
|
55fc49 | 2000-12-30 | Per Hedbor | | {
|
d700c4 | 2006-08-21 | Henrik Grubbström (Grubba) | | 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 | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void init_db( )
|
03156d | 2001-01-29 | Per Hedbor | | {
|
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( )
{
|
c2ef0b | 2006-01-26 | Jonas Wallden | |
|
2f0ae1 | 2007-05-10 | Martin Stjernholm | |
|
c2ef0b | 2006-01-26 | Jonas Wallden | | int now = time();
mapping info = localtime(now);
int wait = (int) ((24 - info->hour) + 24 + 4.5) * 3600 + random(500);
background_run(wait, do_cleanup);
flush(now - 7 * 3600 * 24);
|
5c1b62 | 2001-08-01 | Per Hedbor | | }
|
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()
{
|
ff2cc9 | 2006-10-13 | Martin Stjernholm | | if (mixed err = catch(sync_meta())) {
|
e7ac49 | 2003-04-06 | Anders Johansson | | report_warning("Failed to sync cached atimes for "+name+"\n");
|
ff2cc9 | 2006-10-13 | Martin Stjernholm | | #if 0
#ifdef DEBUG
report_debug (describe_backtrace (err));
#endif
#endif
}
|
2ff846 | 1999-09-02 | Per Hedbor | | }
}
|
254e97 | 2006-03-15 | Marcus Wellhardh | | class ArgCache
{
#undef QUERY
#define QUERY(X,Y...) db->query(X,Y)
Sql.Sql db;
string name;
#define CACHE_SIZE 900
Thread.Mutex mutex = Thread.Mutex();
|
d307c7 | 2008-08-06 | Martin Stjernholm | | # define LOCK() mixed __ = mutex->lock (2)
|
7b805b | 2006-11-16 | Martin Stjernholm | |
|
254e97 | 2006-03-15 | Marcus Wellhardh | | #ifdef ARGCACHE_DEBUG
#define dwerror(ARGS...) werror(ARGS)
#else
#define dwerror(ARGS...) 0
#endif
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping(string|int:mixed) cache = ([ ]);
|
254e97 | 2006-03-15 | Marcus Wellhardh | |
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void setup_table()
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
|
a730d5 | 2008-02-05 | Marcus Wellhardh | | if(catch(QUERY("SELECT id FROM "+name+"2 LIMIT 0")))
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
master()->resolv("DBManager.is_module_table")
( 0, "local", name+"2",
"The argument cache, used to map between "
"a unique string and an argument mapping" );
catch(QUERY("DROP TABLE "+name+"2" ));
QUERY("CREATE TABLE "+name+"2 ("
"id CHAR(32) PRIMARY KEY, "
"ctime DATETIME NOT NULL, "
"atime DATETIME NOT NULL, "
|
464a08 | 2006-11-16 | Martin Stjernholm | | "rep_time DATETIME NOT NULL, "
|
4d2304 | 2007-07-17 | Martin Jonsson | | "contents MEDIUMBLOB NOT NULL)");
|
254e97 | 2006-03-15 | Marcus Wellhardh | | }
|
464a08 | 2006-11-16 | Martin Stjernholm | |
|
a730d5 | 2008-02-05 | Marcus Wellhardh | | if (catch (QUERY ("SELECT rep_time FROM " + name + "2 LIMIT 0")))
|
464a08 | 2006-11-16 | Martin Stjernholm | | {
QUERY ("ALTER TABLE " + name + "2"
" ADD rep_time DATETIME NOT NULL"
" AFTER atime");
}
|
4d2304 | 2007-07-17 | Martin Jonsson | |
catch {
array(mapping(string:mixed)) res =
QUERY("DESCRIBE "+name+"2 contents");
if(res[0]->Type == "blob") {
QUERY("ALTER TABLE "+name+"2 MODIFY contents MEDIUMBLOB NOT NULL");
werror("ArgCache: Extending \"contents\" field in table \"%s2\" from BLOB to MEDIUMBLOB.\n", name);
}
};
|
254e97 | 2006-03-15 | Marcus Wellhardh | | }
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void init_db()
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
cache = ([]);
db = dbm_cached_get("local");
setup_table( );
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void create( string _name )
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
name = _name;
init_db();
master()->resolv( "DBManager.add_dblist_changed_callback" )( init_db );
get_plugins();
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected string read_encoded_args( string id, int dont_update_atime )
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
LOCK();
array res = QUERY("SELECT contents FROM "+name+"2 "
" WHERE id = %s", id);
if(!sizeof(res))
return 0;
|
464a08 | 2006-11-16 | Martin Stjernholm | | if (!dont_update_atime)
QUERY("UPDATE "+name+"2 "
" SET atime = NOW() "
" WHERE id = %s", id);
|
254e97 | 2006-03-15 | Marcus Wellhardh | | return res[0]->contents;
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected void create_key( string id, string encoded_args )
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
LOCK();
array(mapping) rows =
QUERY("SELECT id, contents FROM "+name+"2 WHERE id = %s", id );
foreach( rows, mapping row )
if( row->contents != encoded_args ) {
report_error("ArgCache.create_key(): "
"Duplicate key found! Please report this to support@roxen.com: "
"id: %O, old data: %O, new data: %O\n",
id, row->contents, encoded_args);
error("ArgCache.create_key() Duplicate key found!\n");
}
|
464a08 | 2006-11-16 | Martin Stjernholm | | if(sizeof(rows)) {
QUERY("UPDATE "+name+"2 "
" SET atime = NOW() "
" WHERE id = %s", id);
|
254e97 | 2006-03-15 | Marcus Wellhardh | | return;
|
464a08 | 2006-11-16 | Martin Stjernholm | | }
|
254e97 | 2006-03-15 | Marcus Wellhardh | |
QUERY( "INSERT INTO "+name+"2 "
"(id, contents, ctime, atime) VALUES "
|
2cb514 | 2006-08-21 | Henrik Grubbström (Grubba) | | "(%s, " MYSQL__BINARY "%s, NOW(), NOW())", id, encoded_args );
|
254e97 | 2006-03-15 | Marcus Wellhardh | |
dwerror("ArgCache: Create new key %O\n", id);
(plugins->create_key-({0}))( id, encoded_args );
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected array plugins;
protected void get_plugins()
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
plugins = ({});
foreach( ({ "../local/arg_cache_plugins", "arg_cache_plugins" }), string d)
if( file_stat( d ) )
foreach( glob("*.pike", get_dir( d )), string f )
{
object plug = ((program)(d+"/"+f))(this_object());
if( !plug->disabled )
plugins += ({ plug });
}
}
|
fc4039 | 2008-08-15 | Martin Stjernholm | | protected mapping plugins_read_encoded_args( string id )
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
mapping args;
foreach( (plugins->read_encoded_args - ({0})), function(string:mapping) f )
if( args = f( id ) )
return args;
return 0;
}
string store( mapping args )
{
string encoded_args = encode_value_canonic( args );
|
4e3207 | 2009-01-09 | Stephen R. van den Berg | | string id = Gmp.mpz(Crypto.SHA1.hash(encoded_args), 256)->digits(36);
|
254e97 | 2006-03-15 | Marcus Wellhardh | | if( cache[ id ] )
return id;
create_key(id, encoded_args);
if( !cache[ id ] )
cache[ id ] = args+([]);
if( sizeof( cache ) >= CACHE_SIZE )
cache = ([]);
return id;
}
mapping lookup( string id )
{
if( cache[id] )
return cache[id] + ([]);
|
464a08 | 2006-11-16 | Martin Stjernholm | | string encoded_args = (read_encoded_args(id, 0) ||
plugins_read_encoded_args(id));
|
254e97 | 2006-03-15 | Marcus Wellhardh | | if(!encoded_args) {
error("Requesting unknown key (not found in db)\n");
}
mapping args = decode_value(encoded_args);
cache[id] = args + ([]);
if( sizeof( cache ) >= CACHE_SIZE )
|
464a08 | 2006-11-16 | Martin Stjernholm | |
|
254e97 | 2006-03-15 | Marcus Wellhardh | | cache = ([]);
return args;
}
void delete( string id )
|
2751da | 2006-12-12 | Martin Stjernholm | |
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
LOCK();
(plugins->delete-({0}))( id );
m_delete( cache, id );
QUERY( "DELETE FROM "+name+"2 WHERE id = %s", id );
}
|
2751da | 2006-12-12 | Martin Stjernholm | |
int key_exists( string id )
{
if( cache[id] ) return 1;
if (read_encoded_args(id, 0) || plugins_read_encoded_args(id)) return 1;
return 0;
}
|
254e97 | 2006-03-15 | Marcus Wellhardh | |
#define SECRET_TAG "££"
|
464a08 | 2006-11-16 | Martin Stjernholm | | int write_dump(Stdio.File file, int from_time)
|
254e97 | 2006-03-15 | Marcus Wellhardh | | {
constant FETCH_ROWS = 10000;
|
464a08 | 2006-11-16 | Martin Stjernholm | | int entry_count = 0;
|
254e97 | 2006-03-15 | Marcus Wellhardh | |
if( !has_value((plugins->is_functional-({0}))(), 1) )
{
int cursor;
array(string) ids;
do {
|
464a08 | 2006-11-16 | Martin Stjernholm | |
|
254e97 | 2006-03-15 | Marcus Wellhardh | | if(from_time)
ids =
(array(string))
QUERY( "SELECT id from "+name+"2 "
|
464a08 | 2006-11-16 | Martin Stjernholm | | " WHERE rep_time >= FROM_UNIXTIME(%d) "
|
254e97 | 2006-03-15 | Marcus Wellhardh | | " LIMIT %d, %d", from_time, cursor, FETCH_ROWS)->id;
else
ids =
(array(string))
QUERY( "SELECT id from "+name+"2 "
" LIMIT %d, %d", cursor, FETCH_ROWS)->id;
cursor += FETCH_ROWS;
foreach(ids, string id) {
dwerror("ArgCache.write_dump(): %O\n", id);
|
464a08 | 2006-11-16 | Martin Stjernholm | |
string encoded_args;
if (mapping args = cache[id])
encoded_args = encode_value_canonic (args);
else {
encoded_args = read_encoded_args (id, 1);
if (!encoded_args) error ("ArgCache entry %O disappeared.\n", id);
}
|
254e97 | 2006-03-15 | Marcus Wellhardh | | string s =
|
464a08 | 2006-11-16 | Martin Stjernholm | | MIME.encode_base64(encode_value(({ id, encoded_args }) |