ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | |
a97287 | 2000-12-11 | Per Hedbor | | * $Id: Roxen.pmod,v 1.56 2000/12/11 03:07:22 per Exp $
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | *
* Various helper functions.
*
* Henrik Grubbström 1999-05-03
*/
|
a97287 | 2000-12-11 | Per Hedbor | | #include <roxen.h>
|
69e4cd | 2000-03-09 | Martin Stjernholm | | #include <config.h>
|
88bff1 | 2000-09-12 | Per Hedbor | | #include <version.h>
|
3c4c6e | 2000-11-02 | Per Hedbor | | #include <module.h>
|
a97287 | 2000-12-11 | Per Hedbor | | #include <variables.h>
#include <stat.h>
#ifdef HTTP_DEBUG
# define HTTP_WERR(X) werror("HTTP: "+X+"\n");
#else
# define HTTP_WERR(X)
#endif
#define roxen roxenp()
string http_res_to_string( mapping file, RequestID id )
{
mapping(string:string|array(string)) heads=
([
"Content-type":[string]file["type"],
"Server":replace(roxen->version(), " ", "·"),
"Date":http_date([int]id->time)
]);
if(file->encoding)
heads["Content-Encoding"] = [string]file->encoding;
if(!file->error)
file->error=200;
if(file->expires)
heads->Expires = http_date([int]file->expires);
if(!file->len)
{
if(objectp(file->file))
if(!file->stat && !(file->stat=([mapping(string:mixed)]id->misc)->stat))
file->stat = (array(int))file->file->stat();
array fstat;
if(arrayp(fstat = file->stat))
{
if(file->file && !file->len)
file->len = fstat[1];
heads["Last-Modified"] = http_date([int]fstat[3]);
}
if(stringp(file->data))
file->len += strlen([string]file->data);
}
if(mappingp(file->extra_heads))
heads |= file->extra_heads;
if(mappingp(([mapping(string:mixed)]id->misc)->moreheads))
heads |= ([mapping(string:mixed)]id->misc)->moreheads;
array myheads=({id->prot+" "+(file->rettext||errors[file->error])});
foreach(indices(heads), string h)
if(arrayp(heads[h]))
foreach([array(string)]heads[h], string tmp)
myheads += ({ `+(h,": ", tmp)});
else
myheads += ({ `+(h, ": ", heads[h])});
if(file->len > -1)
myheads += ({"Content-length: " + file->len });
string head_string = (myheads+({"",""}))*"\r\n";
if(id->conf) {
id->conf->hsent+=strlen(head_string||"");
if(id->method != "HEAD")
id->conf->sent+=(file->len>0 ? file->len : 1000);
}
if(id->method != "HEAD")
head_string+=(file->data||"")+(file->file?file->file->read():"");
return head_string;
}
mapping http_low_answer( int errno, string data )
{
if(!data) data="";
HTTP_WERR("Return code "+errno+" ("+data+")");
return
([
"error" : errno,
"data" : data,
"len" : strlen( data ),
"type" : "text/html",
]);
}
mapping http_pipe_in_progress()
{
HTTP_WERR("Pipe in progress");
return ([ "file":-1, "pipe":1, ]);
}
mapping http_rxml_answer( string rxml, RequestID id,
void|Stdio.File file,
void|string type )
{
rxml =
([function(string,RequestID,Stdio.File:string)]id->conf->parse_rxml)
(rxml, id, file);
HTTP_WERR("RXML answer ("+(type||"text/html")+")");
return (["data":rxml,
"type":(type||"text/html"),
"stat":id->misc->defines[" _stat"],
"error":id->misc->defines[" _error"],
"rettext":id->misc->defines[" _rettext"],
"extra_heads":id->misc->defines[" _extra_heads"],
]);
}
mapping http_try_again( float delay )
{
return ([ "try_again_later":delay ]);
}
class Delayer
{
RequestID id;
int resumed;
void resume( )
{
if( resumed )
return;
remove_call_out( resume );
resumed = 1;
if( !id )
error("Cannot resume request -- connection close\n");
roxenp()->handle( id->handle_request );
id = 0;
}
void create( RequestID _id, float max_delay )
{
id = _id;
if( max_delay && max_delay > 0.0 )
call_out( resume, max_delay );
}
}
array(object|mapping) http_try_resume( RequestID id, float|void max_delay )
{
Delayer delay = Delayer( id, max_delay );
return ({delay, ([ "try_again":delay ]) });
}
mapping http_string_answer(string text, string|void type)
{
HTTP_WERR("String answer ("+(type||"text/html")+")");
return ([ "data":text, "type":(type||"text/html") ]);
}
mapping http_file_answer(Stdio.File text, string|void type, void|int len)
{
HTTP_WERR("file answer ("+(type||"text/html")+")");
return ([ "file":text, "type":(type||"text/html"), "len":len ]);
}
constant months = ({ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" });
constant days = ({ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" });
static int chd_lt;
static string chd_lf;
string cern_http_date(int t)
{
if( t == chd_lt ) return chd_lf;
string c;
mapping(string:int) lt = localtime(t);
int tzh = lt->timezone/3600 - lt->isdst;
if(tzh > 0)
c="-";
else {
tzh = -tzh;
c="+";
}
chd_lt = t;
return(chd_lf=sprintf("%02d/%s/%04d:%02d:%02d:%02d %s%02d00",
lt->mday, months[lt->mon], 1900+lt->year,
lt->hour, lt->min, lt->sec, c, tzh));
}
string http_date(int t)
{
mapping(string:int) l = gmtime( t );
return(sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
days[l->wday], l->mday, months[l->mon], 1900+l->year,
l->hour, l->min, l->sec));
}
string http_encode_string(string f)
{
return replace(f, ({ "\000", " ", "\t", "\n", "\r", "%", "'", "\"" }),
({"%00", "%20", "%09", "%0a", "%0d", "%25", "%27", "%22"}));
}
string http_encode_cookie(string f)
{
return replace(f, ({ "=", ",", ";", "%" }), ({ "%3d", "%2c", "%3b", "%25"}));
}
string http_encode_url (string f)
{
return replace (f, ({"\000", " ", "\t", "\n", "\r", "%", "'", "\"", "#",
"&", "?", "=", "/", ":"}),
({"%00", "%20", "%09", "%0a", "%0d", "%25", "%27", "%22", "%23",
"%26", "%3f", "%3d", "%2f", "%3a"}));
}
string http_roxen_config_cookie(string from)
{
return "RoxenConfig="+http_encode_cookie(from)
+"; expires=" + http_date (3600*24*365*2 + time (1)) + "; path=/";
}
string http_roxen_id_cookie()
{
return sprintf("RoxenUserID=0x%x; expires=" +
http_date (3600*24*365*2 + time (1)) + "; path=/",
roxen->increase_id());
}
string add_pre_state( string url, multiset state )
{
if(!url)
error("URL needed for add_pre_state()\n");
if(!state || !sizeof(state))
return url;
if(strlen(url)>5 && (url[1] == '(' || url[1] == '<'))
return url;
return "/(" + sort(indices(state)) * "," + ")" + url ;
}
mapping http_redirect( string url, RequestID|void id )
{
if(strlen(url) && url[0] == '/')
{
if(id)
{
if( id->misc->site_prefix_path )
url = replace( [string]id->misc->site_prefix_path + url, "//", "/" );
url = add_pre_state(url,id->prestate);
if(id->misc->host)
{
array(string) h;
HTTP_WERR(sprintf("(REDIR) id->port_obj:%O", id->port_obj));
string prot = id->port_obj->name + "://";
string p = ":" + id->port_obj->default_port;
h = [string]id->misc->host / p - ({""});
if(sizeof(h) == 1)
url=prot+h[0]+url;
else
url=prot+[string]id->misc->host+url;
} else
url = [string]id->conf->query("MyWorldLocation") + url[1..];
}
}
HTTP_WERR("Redirect -> "+http_encode_string(url));
return http_low_answer( 302, "")
+ ([ "extra_heads":([ "Location":http_encode_string( url ) ]) ]);
}
mapping http_stream(Stdio.File from)
{
return ([ "raw":1, "file":from, "len":-1, ]);
}
mapping http_auth_required(string realm, string|void message)
{
if(!message)
message = "<h1>Authentication failed.\n</h1>";
HTTP_WERR("Auth required ("+realm+")");
return http_low_answer(401, message)
+ ([ "extra_heads":([ "WWW-Authenticate":"basic realm=\""+realm+"\"",]),]);
}
mapping http_proxy_auth_required(string realm, void|string message)
{
if(!message)
message = "<h1>Proxy authentication failed.\n</h1>";
return http_low_answer(407, message)
+ ([ "extra_heads":([ "Proxy-Authenticate":"basic realm=\""+realm+"\"",]),]);
}
mapping add_http_header(mapping to, string name, string value)
{
if(to[name]) {
if(arrayp(to[name]))
to[name] += ({ value });
else
to[name] = ({ to[name], value });
}
else
to[name] = value;
return to;
}
string extract_query(string from)
{
if(!from) return "";
if(sscanf(from, "%*s?%s%*[ \t\n]", from))
return (from/"\r")[0];
return "";
}
mapping build_env_vars(string f, RequestID id, string path_info)
{
string addr=id->remoteaddr || "Internal";
mapping(string:string) new = ([]);
RequestID tmpid;
if(id->query && strlen(id->query))
new->INDEX=id->query;
if(path_info && strlen(path_info))
{
string t, t2;
if(path_info[0] != '/')
path_info = "/" + path_info;
t = t2 = "";
if ( ([mapping(string:mixed)]id->misc)->path_info == path_info ) {
new["SCRIPT_NAME"]=id->not_query;
} else {
new["SCRIPT_NAME"]=
id->not_query[0..strlen([string]id->not_query)-strlen(path_info)-1];
}
new["PATH_INFO"]=path_info;
while(1)
{
t2 = id->conf->real_file(path_info, id);
if(t2)
{
new["PATH_TRANSLATED"] = t2 + t;
break;
}
array(string) tmp = path_info/"/" - ({""});
if(!sizeof(tmp))
break;
path_info = "/" + (tmp[0..sizeof(tmp)-2]) * "/";
t = tmp[-1] +"/" + t;
}
} else
new["SCRIPT_NAME"]=id->not_query;
tmpid = id;
while(tmpid->misc->orig)
tmpid = tmpid->misc->orig;
array(string) tmps;
if(sizeof(tmps = tmpid->not_query/"/" - ({""})))
new["DOCUMENT_NAME"]=tmps[-1];
new["DOCUMENT_URI"]= tmpid->not_query;
Stat tmpi;
string real_file=tmpid->conf->real_file(tmpid->not_query||"", tmpid);
if (real_file) {
if(stringp(real_file)) {
if ((tmpi = file_stat(real_file)) &&
sizeof(tmpi)) {
new["LAST_MODIFIED"]=http_date(tmpi[3]);
}
} else {
report_error(sprintf("real_file(%O, %O) returned %O\n",
tmpid->not_query||"", tmpid, real_file));
}
}
if(string tmp = id->conf->real_file(new["SCRIPT_NAME"], id))
new["SCRIPT_FILENAME"] = tmp;
if(string tmp = id->conf->real_file("/", id))
new["DOCUMENT_ROOT"] = tmp;
if(!new["PATH_TRANSLATED"])
m_delete(new, "PATH_TRANSLATED");
else if(new["PATH_INFO"][-1] != '/' && new["PATH_TRANSLATED"][-1] == '/')
new["PATH_TRANSLATED"] =
new["PATH_TRANSLATED"][0..strlen(new["PATH_TRANSLATED"])-2];
mapping hdrs;
if ((hdrs = id->request_headers)) {
foreach(indices(hdrs) - ({ "authorization", "proxy-authorization",
"security-scheme", }), string h) {
string hh = "HTTP_" + replace(upper_case(h),
({ " ", "-", "\0", "=" }),
({ "_", "_", "", "_" }));
new[hh] = replace(hdrs[h], ({ "\0" }), ({ "" }));
}
if (!new["HTTP_HOST"]) {
if(objectp(id->my_fd) && id->my_fd->query_address(1))
new["HTTP_HOST"] = replace(id->my_fd->query_address(1)," ",":");
}
} else {
if(id->misc->host)
new["HTTP_HOST"]=id->misc->host;
else if(objectp(id->my_fd) && id->my_fd->query_address(1))
new["HTTP_HOST"]=replace(id->my_fd->query_address(1)," ",":");
if(id->misc["proxy-connection"])
new["HTTP_PROXY_CONNECTION"]=id->misc["proxy-connection"];
if(id->misc->accept) {
if (arrayp(id->misc->accept)) {
new["HTTP_ACCEPT"]=id->misc->accept*", ";
} else {
new["HTTP_ACCEPT"]=(string)id->misc->accept;
}
}
if(id->misc->cookies)
new["HTTP_COOKIE"] = id->misc->cookies;
if(sizeof(id->pragma))
new["HTTP_PRAGMA"]=indices(id->pragma)*", ";
if(stringp(id->misc->connection))
new["HTTP_CONNECTION"]=id->misc->connection;
new["HTTP_USER_AGENT"] = id->client*" ";
if(id->referer && sizeof(id->referer))
new["HTTP_REFERER"] = id->referer*"";
}
new["REMOTE_ADDR"]=addr;
if(roxen->quick_ip_to_host(addr) != addr)
new["REMOTE_HOST"]=roxen->quick_ip_to_host(addr);
catch {
if(id->my_fd)
new["REMOTE_PORT"] = (id->my_fd->query_address()/" ")[1];
};
if (id->query && sizeof(id->query)) {
new["QUERY_STRING"] = id->query;
}
if(id->realauth)
new["REMOTE_USER"] = (id->realauth / ":")[0];
if(id->auth && id->auth[0])
new["ROXEN_AUTHENTICATED"] = "1";
if(id->data && strlen(id->data))
{
if(id->misc["content-type"])
new["CONTENT_TYPE"]=id->misc["content-type"];
else
new["CONTENT_TYPE"]="application/x-www-form-urlencoded";
new["CONTENT_LENGTH"]=(string)strlen(id->data);
}
if(id->query && strlen(id->query))
new["INDEX"]=id->query;
new["REQUEST_METHOD"]=id->method||"GET";
new["SERVER_PORT"] = id->my_fd?
((id->my_fd->query_address(1)||"foo unknown")/" ")[1]: "Internal";
return new;
}
mapping build_roxen_env_vars(RequestID id)
{
mapping(string:string) new = ([]);
string tmp;
if(id->cookies->RoxenUserID)
new["ROXEN_USER_ID"]=id->cookies->RoxenUserID;
new["COOKIES"] = "";
foreach(indices(id->cookies), tmp)
{
new["COOKIE_"+tmp] = id->cookies[tmp];
new["COOKIES"]+= tmp+" ";
}
foreach(indices(id->config), tmp)
{
new["WANTS_"+replace(tmp, " ", "_")]="true";
if(new["CONFIGS"])
new["CONFIGS"] += " " + replace(tmp, " ", "_");
else
new["CONFIGS"] = replace(tmp, " ", "_");
}
foreach(indices(id->variables), tmp)
{
string name = replace(tmp," ","_");
if (id->variables[tmp] && (sizeof(id->variables[tmp]) < 8192)) {
new["QUERY_"+name] = replace(id->variables[tmp],"\000"," ");
new["VAR_"+name] = replace(id->variables[tmp],"\000","#");
}
if(new["VARIABLES"])
new["VARIABLES"]+= " " + name;
else
new["VARIABLES"]= name;
}
foreach(indices(id->prestate), tmp)
{
new["PRESTATE_"+replace(tmp, " ", "_")]="true";
if(new["PRESTATES"])
new["PRESTATES"] += " " + replace(tmp, " ", "_");
else
new["PRESTATES"] = replace(tmp, " ", "_");
}
foreach(indices(id->supports), tmp)
{
new["SUPPORTS_"+replace(tmp-",", " ", "_")]="true";
if (new["SUPPORTS"])
new["SUPPORTS"] += " " + replace(tmp, " ", "_");
else
new["SUPPORTS"] = replace(tmp, " ", "_");
}
return new;
}
string decode_mode(int m)
{
string s;
s="";
if(S_ISLNK(m)) s += "Symbolic link";
else if(S_ISREG(m)) s += "File";
else if(S_ISDIR(m)) s += "Dir";
else if(S_ISCHR(m)) s += "Special";
else if(S_ISBLK(m)) s += "Device";
else if(S_ISFIFO(m)) s += "FIFO";
else if(S_ISSOCK(m)) s += "Socket";
else if((m&0xf000)==0xd000) s+="Door";
else s+= "Unknown";
s+=", ";
if(S_ISREG(m) || S_ISDIR(m))
{
s+="<tt>";
if(m&S_IRUSR) s+="r"; else s+="-";
if(m&S_IWUSR) s+="w"; else s+="-";
if(m&S_IXUSR) s+="x"; else s+="-";
if(m&S_IRGRP) s+="r"; else s+="-";
if(m&S_IWGRP) s+="w"; else s+="-";
if(m&S_IXGRP) s+="x"; else s+="-";
if(m&S_IROTH) s+="r"; else s+="-";
if(m&S_IWOTH) s+="w"; else s+="-";
if(m&S_IXOTH) s+="x"; else s+="-";
s+="</tt>";
} else {
s+="--";
}
return s;
}
int _match(string w, array (string) a)
{
if(!stringp(w))
return -1;
foreach(a, string q)
if(stringp(q) && strlen(q) && glob(q, w))
return 1;
}
string short_name(string long_name)
{
long_name = replace(long_name, " ", "_");
return lower_case(long_name);
}
string strip_config(string from)
{
sscanf(from, "/<%*s>%s", from);
return from;
}
string strip_prestate(string from)
{
sscanf(from, "/(%*s)%s", from);
return from;
}
#define _error defines[" _error"]
#define _extra_heads defines[" _extra_heads"]
#define _rettext defines[" _rettext"]
string parse_rxml(string what, RequestID id,
void|Stdio.File file,
void|mapping(string:mixed) defines)
{
if(!objectp(id)) error("No id passed to parse_rxml\n");
return id->conf->parse_rxml( what, id, file, defines );
}
constant iso88591
=([ " ": " ",
"¡": "¡",
"¢": "¢",
"£": "£",
"¤": "¤",
"¥": "¥",
"¦": "¦",
"§": "§",
"¨": "¨",
"©": "©",
"ª": "ª",
"«": "«",
"¬": "¬",
"­": "",
"®": "®",
"¯": "¯",
"°": "°",
"±": "±",
"²": "²",
"³": "³",
"´": "´",
"µ": "µ",
"¶": "¶",
"·": "·",
"¸": "¸",
"¹": "¹",
"º": "º",
"»": "»",
"¼": "¼",
"½": "½",
"¾": "¾",
"¿": "¿",
"À": "À",
"Á": "Á",
"Â": "Â",
"Ã": "Ã",
"Ä": "Ä",
"Å": "Å",
"Æ": "Æ",
"Ç": "Ç",
"È": "È",
"É": "É",
"Ê": "Ê",
"Ë": "Ë",
"Ì": "Ì",
"Í": "Í",
"Î": "Î",
"Ï": "Ï",
"Ð": "Ð",
"Ñ": "Ñ",
"Ò": "Ò",
"Ó": "Ó",
"Ô": "Ô",
"Õ": "Õ",
"Ö": "Ö",
"×": "×",
"Ø": "Ø",
"Ù": "Ù",
"Ú": "Ú",
"Û": "Û",
"Ü": "Ü",
"Ý": "Ý",
"Þ": "Þ",
"ß": "ß",
"à": "à",
"á": "á",
"â": "â",
"ã": "ã",
"ä": "ä",
"å": "å",
"æ": "æ",
"ç": "ç",
"è": "è",
"é": "é",
"ê": "ê",
"ë": "ë",
"ì": "ì",
"í": "í",
"î": "î",
"ï": "ï",
"ð": "ð",
"ñ": "ñ",
"ò": "ò",
"ó": "ó",
"ô": "ô",
"õ": "õ",
"ö": "ö",
"÷": "÷",
"ø": "ø",
"ù": "ù",
"ú": "ú",
"û": "û",
"ü": "ü",
"ý": "ý",
"þ": "þ",
"ÿ": "ÿ",
]);
constant international
=([ "Œ": "\x0152",
"œ": "\x0153",
"Š": "\x0160",
"š": "\x0161",
"Ÿ": "\x0178",
"ˆ": "\x02C6",
"˜": "\x02DC",
" ": "\x2002",
" ": "\x2003",
" ": "\x2009",
"‌": "\x200C",
"‍": "\x200D",
"‎": "\x200E",
"‏": "\x200F",
"–": "\x2013",
"—": "\x2014",
"‘": "\x2018",
"’": "\x2019",
"‚": "\x201A",
"“": "\x201C",
"”": "\x201D",
"„": "\x201E",
"†": "\x2020",
"‡": "\x2021",
"‰": "\x2030",
"‹": "\x2039",
"›": "\x203A",
"€": "\x20AC",
]);
constant symbols
=([ "ƒ": "\x0192",
"ϑ": "\x03D1",
"ϒ": "\x03D2",
"ϖ": "\x03D6",
"•": "\x2022",
"…": "\x2026",
"′": "\x2032",
"″": "\x2033",
"‾": "\x203E",
"⁄": "\x2044",
"℘": "\x2118",
"ℑ": "\x2111",
"ℜ": "\x211C",
"™": "\x2122",
"ℵ": "\x2135",
"←": "\x2190",
"↑": "\x2191",
"→": "\x2192",
"↓": "\x2193",
"↔": "\x2194",
"↵": "\x21B5",
"⇐": "\x21D0",
"⇑": "\x21D1",
"⇒": "\x21D2",
"⇓": "\x21D3",
"⇔": "\x21D4",
"∀": "\x2200",
"∂": "\x2202",
"∃": "\x2203",
"∅": "\x2205",
"∇": "\x2207",
"∈": "\x2208",
"∉": "\x2209",
"∋": "\x220B",
"∏": "\x220F",
"∑": "\x2211",
"−": "\x2212",
"∗": "\x2217",
"√": "\x221A",
"∝": "\x221D",
"∞": "\x221E",
"∠": "\x2220",
"∧": "\x2227",
"∨": "\x2228",
"∩": "\x2229",
"∪": "\x222A",
"∫": "\x222B",
"∴": "\x2234",
"∼": "\x223C",
"≅": "\x2245",
"≈": "\x2248",
"≠": "\x2260",
"≡": "\x2261",
"≤": "\x2264",
"≥": "\x2265",
"⊂": "\x2282",
"⊃": "\x2283",
"⊄": "\x2284",
"⊆": "\x2286",
"⊇": "\x2287",
"⊕": "\x2295",
"⊗": "\x2297",
"⊥": "\x22A5",
"⋅": "\x22C5",
"⌈": "\x2308",
"⌉": "\x2309",
"⌊": "\x230A",
"⌋": "\x230B",
"⟨": "\x2329",
"⟩": "\x232A",
"◊": "\x25CA",
"♠": "\x2660",
"♣": "\x2663",
"♥": "\x2665",
"♦": "\x2666",
]);
constant greek
= ([ "Α": "\x391",
"Β": "\x392",
"Γ": "\x393",
"Δ": "\x394",
"Ε": "\x395",
"Ζ": "\x396",
"Η": "\x397",
"Θ": "\x398",
"Ι": "\x399",
"Κ": "\x39A",
"Λ": "\x39B",
"Μ": "\x39C",
"Ν": "\x39D",
"Ξ": "\x39E",
"Ο": "\x39F",
"Π": "\x3A0",
"Ρ": "\x3A1",
"Σ": "\x3A3",
"Τ": "\x3A4",
"Υ": "\x3A5",
"Φ": "\x3A6",
"Χ": "\x3A7",
"Ψ": "\x3A8",
"Ω": "\x3A9",
"α": "\x3B1",
"β": "\x3B2",
"γ": "\x3B3",
"δ": "\x3B4",
"ε": "\x3B5",
"ζ": "\x3B6",
"η": "\x3B7",
"θ": "\x3B8",
"ι": "\x3B9",
"κ": "\x3BA",
"λ": "\x3BB",
"μ": "\x3BC",
"ν": "\x3BD",
"ξ": "\x3BE",
"ο": "\x3BF",
"π": "\x3C0",
"ρ": "\x3C1",
"ς": "\x3C2",
"σ": "\x3C3",
"τ": "\x3C4",
"υ": "\x3C5",
"φ": "\x3C6",
"χ": "\x3C7",
"ψ": "\x3C8",
"ω": "\x3C9",
]);
constant replace_entities=indices( iso88591 )+indices( international )+indices( symbols )+indices( greek )+({"<",">","&",""","'",""",""","'","�"});
constant replace_values =values( iso88591 )+values( international )+values( symbols )+values( greek )+({"<",">","&","\"","\'","\"","\"","\'","\000"});
constant safe_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"/"";
constant empty_strings = ({""})*sizeof(safe_characters);
int is_safe_string(string in)
{
return strlen(in) && !strlen(replace(in, safe_characters, empty_strings));
}
string make_entity( string q )
{
return "&"+q+";";
}
string make_tag_attributes(mapping(string:string) in)
{
if(!in || !sizeof(in)) return "";
string res="";
foreach(indices(in), string a)
res+=" "+a+"=\""+html_encode_string((string)in[a])+"\"";
return res;
}
string make_tag(string name, mapping(string:string) args, void|int xml)
{
return "<"+name+make_tag_attributes(args,xml)+(xml?" /":"")+">";
}
string make_container(string name, mapping(string:string) args, string content)
{
if(args["/"]=="/") m_delete(args, "/");
return make_tag(name,args)+content+"</"+name+">";
}
string dirname( string file )
{
if(!file)
return "/";
if(file[-1] == '/')
if(strlen(file) > 1)
return file[0..strlen(file)-2];
else
return file;
array tmp=file/"/";
if(sizeof(tmp)==2 && tmp[0]=="")
return "/";
return tmp[0..sizeof(tmp)-2]*"/";
}
string conv_hex( int color )
{
return sprintf("#%06X", color);
}
string add_config( string url, array config, multiset prestate )
{
if(!sizeof(config))
return url;
if(strlen(url)>5 && (url[1] == '(' || url[1] == '<'))
return url;
return "/<" + config * "," + ">" + add_pre_state(url, prestate);
}
string msectos(int t)
{
if(t<1000)
{
return sprintf("0.%02d sec", t/10);
} else if(t<6000) {
return sprintf("%d.%02d sec", t/1000, (t%1000 + 5) / 10);
} else if(t<3600000) {
return sprintf("%d:%02d m:s", t/60000, (t%60000)/1000);
}
return sprintf("%d:%02d h:m", t/3600000, (t%3600000)/60000);
}
string extension( string f, RequestID|void id)
{
string ext, key;
if(!f || !strlen(f)) return "";
if(!id || !(ext = [string]id->misc[key="_ext_"+f])) {
sscanf(reverse(f), "%s.%*s", ext);
if(!ext) ext = "";
else {
ext = lower_case(reverse(ext));
if(sizeof (ext) && (ext[-1] == '~' || ext[-1] == '#'))
ext = ext[..strlen(ext)-2];
}
if(id) id->misc[key]=ext;
}
return ext;
}
int(0..1) backup_extension( string f )
{
if(!strlen(f))
return 1;
return (f[-1] == '#' || f[-1] == '~' || f[0..1]==".#"
|| (f[-1] == 'd' && sscanf(f, "%*s.old"))
|| (f[-1] == 'k' && sscanf(f, "%*s.bak")));
}
array(string) win_drive_prefix(string path)
{
#ifdef __NT__
string prefix;
if (sscanf(path, "\\\\%s%*[\\/]%s", prefix, string path_end) == 3) {
return ({ "\\\\" + prefix, "/" + path_end });
} else if (sscanf(path, "%1s:%s", prefix, path) == 2) {
return ({ prefix + ":", path });
}
#endif
return ({ "", path });
}
string simplify_path(string file)
{
if(!strlen(file) || (!has_value(file, "./") && (file[-1] != '.') &&
!has_value (file, "//")))
return file;
int t2,t1;
[string prefix, file] = win_drive_prefix(file);
if(file[0] != '/')
t2 = 1;
if(strlen(file) > 1
&& file[-2]=='/'
&& ((file[-1] == '/') || (file[-1]=='.'))
)
t1=1;
file=combine_path("/", file);
if(t1) file += "/.";
if(t2) return prefix + file[1..];
return prefix + file;
}
string short_date(int timestamp)
{
int date = time(1);
if(ctime(date)[20..23] != ctime(timestamp)[20..23])
return ctime(timestamp)[4..9] +" "+ ctime(timestamp)[20..23];
return ctime(timestamp)[4..9] +" "+ ctime(timestamp)[11..15];
}
string int2roman(int m)
{
string res="";
if (m>10000000||m<0) return "que";
while (m>999) { res+="M"; m-=1000; }
if (m>899) { res+="CM"; m-=900; }
else if (m>499) { res+="D"; m-=500; }
else if (m>399) { res+="CD"; m-=400; }
while (m>99) { res+="C"; m-=100; }
if (m>89) { res+="XC"; m-=90; }
else if (m>49) { res+="L"; m-=50; }
else if (m>39) { res+="XL"; m-=40; }
while (m>9) { res+="X"; m-=10; }
if (m>8) return res+"IX";
else if (m>4) { res+="V"; m-=5; }
else if (m>3) return res+"IV";
while (m) { res+="I"; m--; }
return res;
}
string number2string(int n, mapping m, array|function names)
{
string s;
switch (m->type)
{
case "string":
if (functionp(names)) {
s=([function(int:string)]names)(n);
break;
}
if (n<0 || n>=sizeof(names))
s="";
else
s=([array(string)]names)[n];
break;
case "roman":
s=int2roman(n);
break;
default:
return (string)n;
}
switch(m["case"]) {
case "lower": return lower_case(s);
case "upper": return upper_case(s);
case "capitalize": return capitalize(s);
}
#ifdef old_rxml_compat
if (m->lower) return lower_case(s);
if (m->upper) return upper_case(s);
if (m->cap||m->capitalize) return capitalize(s);
#endif
return s;
}
string image_from_type( string t )
{
if(t)
{
sscanf(t, "%s/", t);
switch(t)
{
case "audio":
case "sound":
return "internal-gopher-sound";
case "image":
return "internal-gopher-image";
case "application":
return "internal-gopher-binary";
case "text":
return "internal-gopher-text";
}
}
return "internal-gopher-unknown";
}
#define PREFIX ({ "bytes", "kb", "Mb", "Gb", "Tb", "Hb" })
string sizetostring( int size )
{
if(size<0) return "--------";
float s = (float)size;
size=0;
if(s<1024.0) return (int)s+" bytes";
while( s > 1024.0 )
{
s /= 1024.0;
size ++;
}
return sprintf("%.1f %s", s, PREFIX[ size ]);
}
mapping proxy_auth_needed(RequestID id)
{
int|mapping res = id->conf->check_security(proxy_auth_needed, id);
if(res)
{
if(res==1)
return http_low_answer(403, "You are not allowed to access this proxy");
if(!mappingp(res))
return 0;
res->error = 407;
return [mapping]res;
}
return 0;
}
string program_filename()
{
return master()->program_name(this_object())||"";
}
string program_directory()
{
array(string) p = program_filename()/"/";
return (sizeof(p)>1? p[..sizeof(p)-2]*"/" : getcwd());
}
string html_encode_string(LocaleString str)
{
return replace((string)str, ({"&", "<", ">", "\"", "\'", "\000" }),
({"&", "<", ">", """, "'", "�"}));
}
string html_decode_string(LocaleString str)
{
return replace((string)str, replace_entities, replace_values);
}
string html_encode_tag_value(LocaleString str)
{
return "\"" + replace((string)str, ({"&", "\"", "<"}), ({"&", """, "<"})) + "\"";
}
string strftime(string fmt, int t)
{
if(!sizeof(fmt)) return "";
mapping lt = localtime(t);
fmt=replace(fmt, "%%", "\0");
array(string) a = fmt/"%";
string res = a[0];
foreach(a[1..], string key) {
if(key=="") continue;
switch(key[0]) {
case 'a':
res += ({ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" })[lt->wday];
break;
case 'A':
res += ({ "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" })[lt->wday];
break;
case 'b':
case 'h':
res += ({ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" })[lt->mon];
break;
case 'B':
res += ({ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" })[lt->mon];
break;
case 'c':
res += strftime(sprintf("%%a %%b %02d %02d:%02d:%02d %04d",
lt->mday, lt->hour, lt->min, lt->sec, 1900 + lt->year), t);
break;
case 'C':
res += sprintf("%02d", 19 + lt->year/100);
break;
case 'd':
res += sprintf("%02d", lt->mday);
break;
case 'D':
res += strftime("%m/%d/%y", t);
break;
case 'e':
res += sprintf("%2d", lt->mday);
break;
case 'E':
case 'O':
key = key[1..];
break;
case 'H':
res += sprintf("%02d", lt->hour);
break;
case 'I':
res += sprintf("%02d", 1 + (lt->hour + 11)%12);
break;
case 'j':
res += sprintf("%03d", lt->yday);
break;
case 'k':
res += sprintf("%2d", lt->hour);
break;
case 'l':
res += sprintf("%2d", 1 + (lt->hour + 11)%12);
break;
case 'm':
res += sprintf("%02d", lt->mon + 1);
break;
case 'M':
res += sprintf("%02d", lt->min);
break;
case 'n':
res += "\n";
break;
case 'p':
res += lt->hour<12 ? "a.m." : "p.m.";
break;
case 'r':
res += strftime("%l:%M %p", t);
break;
case 'R':
res += sprintf("%02d:%02d", lt->hour, lt->min);
break;
case 'S':
res += sprintf("%02", lt->sec);
break;
case 't':
res += "\t";
break;
case 'T':
case 'X':
res += sprintf("%02d:%02d:%02d", lt->hour, lt->min, lt->sec);
break;
case 'u':
res += sprintf("%d", lt->wday + 1);
break;
case 'w':
res += sprintf("%d", lt->wday);
break;
case 'x':
res += strftime("%a %b %d %Y", t);
break;
case 'y':
res += sprintf("%02d", lt->year % 100);
break;
case 'Y':
res += sprintf("%04d", 1900 + lt->year);
break;
case 'U':
res += sprintf("%02d", ((lt->yday-1+lt->wday)/7));
break;
case 'V':
res += sprintf("%02d", Calendar.ISO.Second(t)->week_no());
break;
case 'W':
res += sprintf("%02d", ((lt->yday+(5+lt->wday)%7)/7));
break;
case 'Z':
}
res+=key[1..];
}
return replace(res, "\0", "%");
}
RoxenModule get_module (string modname)
{
string cname, mname;
int mid = 0;
if (sscanf (modname, "%s/%s", cname, mname) != 2 ||
!sizeof (cname) || !sizeof(mname)) return 0;
sscanf (mname, "%s#%d", mname, mid);
if (Configuration conf = roxen->get_configuration (cname))
if (mapping moddata = conf->modules[mname])
return moddata->copies[mid];
return 0;
}
string get_modname (RoxenModule module)
{
if (!module) return 0;
if (Configuration conf = module->my_configuration())
if (string mname = conf->otomod[module])
return conf->name + "/" + mname;
return 0;
}
string get_modfullname (RoxenModule module)
{
if (module) {
string|mapping(string:string) name = 0;
if (module->query)
catch {
mixed res = module->query ("_name");
if (res) name = (string) res;
};
if (!(name && sizeof (name)) && module->query_name)
name = module->query_name();
if (!(name && sizeof (name)))
name = [string]module->register_module()[1];
if (mappingp (name))
name = name->standard;
return name;
}
else return 0;
}
string roxen_encode( string val, string encoding )
{
switch (encoding) {
case "":
case "none":
return val;
case "http":
return http_encode_string (val);
case "cookie":
return http_encode_cookie (val);
case "url":
return http_encode_url (val);
case "html":
return html_encode_string (val);
case "dtag":
return replace (val, "\"", "\"'\"'\"");
case "stag":
return replace(val, "'", "'\"'\"'");
case "pike":
return replace (val,
({ "\"", "\\", "\n" }),
({ "\\\"", "\\\\", "\\n" }));
case "js":
case "javascript":
return replace (val,
({ "\b", "\014", "\n", "\r", "\t", "\\", "'", "\"" }),
({ "\\b", "\\f", "\\n", "\\r", "\\t", "\\\\",
"\\'", "\\\"" }));
case "mysql":
return replace (val,
({ "\"", "'", "\\" }),
({ "\\\"" , "\\'", "\\\\" }) );
case "sql":
case "oracle":
return replace (val, "'", "''");
case "mysql-dtag":
return replace (val,
({ "\"", "'", "\\" }),
({ "\\\"'\"'\"", "\\'", "\\\\" }));
case "mysql-pike":
return replace (val,
({ "\"", "'", "\\", "\n" }),
({ "\\\\\\\"", "\\\\'",
"\\\\\\\\", "\\n" }) );
case "sql-dtag":
case "oracle-dtag":
return replace (val,
({ "'", "\"" }),
({ "''", "\"'\"'\"" }) );
default:
return 0;
}
}
string fix_relative( string file, RequestID id )
{
string path = id->not_query;
if( !search( file, "http:" ) )
return file;
[string prefix, file] = win_drive_prefix(file);
if(file != "" && file[0] == '/')
;
else if(file != "" && file[0] == '#')
file = path + file;
else
file = dirname(path) + "/" + file;
return simplify_path(prefix + file);
}
Stdio.File open_log_file( string logfile )
{
mapping m = localtime(time(1));
m->year += 1900;
m->mon++;
if(m->mon < 10) m->mon = "0"+m->mon;
if(m->mday < 10) m->mday = "0"+m->mday;
if(m->hour < 10) m->hour = "0"+m->hour;
logfile = replace(logfile,({"%d","%m","%y","%h" }),
({ (string)m->mday, (string)(m->mon),
(string)(m->year),(string)m->hour,}));
if(strlen(logfile))
{
Stdio.File lf=Stdio.File( logfile, "wac");
if(!lf)
{
mkdirhier(logfile);
if(!(lf=Stdio.File( logfile, "wac")))
{
report_error("Failed to open logfile. ("+logfile+"): "
+ strerror( errno() )+"\n");
return 0;
}
}
return lf;
}
return Stdio.stderr;
}
string tagtime(int t, mapping(string:string) m, RequestID id,
function(string, string,
object:function(int, mapping(string:string):string)) language)
{
string res;
if (m->adjust) t+=(int)m->adjust;
string lang;
if(id->misc->defines->theme_language) lang=id->misc->defines->theme_language;
if(m->lang) lang=m->lang;
if(m->strftime)
return strftime(m->strftime, t);
if (m->part)
{
string sp;
if(m->type == "ordered")
{
m->type="string";
sp = "ordered";
}
switch (m->part)
{
case "year":
return number2string(localtime(t)->year+1900,m,
language(lang, sp||"number",id));
case "month":
return number2string(localtime(t)->mon+1,m,
language(lang, sp||"month",id));
case "week":
return number2string(Calendar.ISO.Second(t)->week_no(),
m, language(lang, sp||"number",id));
case "beat":
mapping lt=gmtime(t);
int secs=3600;
secs+=lt->hour*3600;
secs+=lt->min*60;
secs+=lt->sec;
secs%=24*3600;
float beats=secs/86.4;
if(!sp) return sprintf("@%03d",(int)beats);
return number2string((int)beats,m,
language(lang, sp||"number",id));
case "day":
case "wday":
return number2string(localtime(t)->wday+1,m,
language(lang, sp||"day",id));
case "date":
case "mday":
return number2string(localtime(t)->mday,m,
language(lang, sp||"number",id));
case "hour":
return number2string(localtime(t)->hour,m,
language(lang, sp||"number",id));
case "min":
case "minute":
return number2string(localtime(t)->min,m,
language(lang, sp||"number",id));
case "sec":
case "second":
return number2string(localtime(t)->sec,m,
language(lang, sp||"number",id));
case "seconds":
return number2string(t,m,
language(lang, sp||"number",id));
case "yday":
return number2string(localtime(t)->yday,m,
language(lang, sp||"number",id));
default: return "";
}
}
else if(m->type) {
switch(m->type)
{
case "iso":
mapping eris=localtime(t);
if(m->date)
return sprintf("%d-%02d-%02d",
(eris->year+1900), eris->mon+1, eris->mday);
if(m->time)
return sprintf("%02d:%02d:%02d", eris->hour, eris->min, eris->sec);
return sprintf("%d-%02d-%02dT%02d:%02d:%02d",
(eris->year+1900), eris->mon+1, eris->mday,
eris->hour, eris->min, eris->sec);
case "discordian":
#if efun(discdate)
array(string) not=discdate(t);
res=not[0];
if(m->year)
res += " in the YOLD of "+not[1];
if(m->holiday && not[2])
res += ". Celebrate "+not[2];
return res;
#else
return "Discordian date support disabled";
#endif
case "stardate":
#if efun(stardate)
return (string)stardate(t, (int)m->prec||1);
#else
return "Stardate support disabled";
#endif
}
}
res=language(lang, "date", id)(t,m);
if(m["case"])
switch(lower_case(m["case"]))
{
case "upper": return upper_case(res);
case "lower": return lower_case(res);
case "capitalize": return capitalize(res);
}
#ifdef old_rxml_compat
if (m->upper) {
res=upper_case(res);
report_warning("Old RXML in "+(id->query||id->not_query)+
", contains upper attribute in a tag. Use case=\"upper\" instead.");
}
if (m->lower) {
res=lower_case(res);
report_warning("Old RXML in "+(id->query||id->not_query)+
", contains lower attribute in a tag. Use case=\"lower\" instead.");
}
if (m->cap||m->capitalize) {
res=capitalize(res);
report_warning("Old RXML in "+(id->query||id->not_query)+
", contains capitalize or cap attribute in a tag. Use case=\"capitalize\" instead.");
}
#endif
return res;
}
int time_dequantifier(mapping m)
{
float t = 0.0;
if (m->seconds) t+=((float)(m->seconds));
if (m->minutes) t+=((float)(m->minutes))*60;
if (m->beats) t+=((float)(m->beats))*86.4;
if (m->hours) t+=((float)(m->hours))*3600;
if (m->days) t+=((float)(m->days))*86400;
if (m->weeks) t+=((float)(m->weeks))*604800;
if (m->months) t+=((float)(m->months))*(24*3600*30.436849);
if (m->years) t+=((float)(m->years))*(3600*24*365.242190);
return (int)t;
}
class _charset_decoder(object cs)
{
string decode(string what)
{
return cs->clear()->feed(what)->drain();
}
}
function get_client_charset_decoder( string åäö, RequestID|void id )
{
switch( (åäö/"\0")[0] )
{
case "edv":
report_notice( "Warning: Non 8-bit safe client detected (%s)",
(id?id->client*"":"unknown client"));
return 0;
case "åäö":
return 0;
case "\33-Aåäö":
id && id->set_output_charset && id->set_output_charset( "iso-2022" );
return _charset_decoder(Locale.Charset.decoder("iso-2022-jp"))->decode;
case "åäö":
id && id->set_output_charset && id->set_output_charset( "utf-8" );
return utf8_to_string;
case "\214\212\232":
id && id->set_output_charset && id->set_output_charset( "mac" );
return _charset_decoder( Locale.Charset.decoder( "mac" ) )->decode;
case "\0å\0ä\0ö":
id&&id->set_output_charset&&id->set_output_charset(string_to_unicode);
return unicode_to_string;
}
report_warning( "Unable to find charset decoder for åäö == "+åäö+"\n" );
}
|
69e4cd | 2000-03-09 | Martin Stjernholm | |
|
796fb6 | 2000-08-12 | Per Hedbor | |
#if constant( _Roxen )
inherit _Roxen;
#endif
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
#ifdef QUOTA_DEBUG
#define QD_WRITE(X) werror(X)
#else /* !QUOTA_DEBUG */
#define QD_WRITE(X)
#endif /* QUOTA_DEBUG */
|
7e9a0b | 2000-09-16 | Per Hedbor | | #undef CACHE
#undef NOCACHE
#define CACHE(id,X) ([mapping(string:mixed)]id->misc)->cacheable=min(([mapping(string:mixed)]id->misc)->cacheable,X)
#define NOCACHE(id) ([mapping(string:mixed)]id->misc)->cacheable=0
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | class QuotaDB
{
#if constant(create_thread)
object(Thread.Mutex) lock = Thread.Mutex();
|
2543b7 | 2000-07-02 | Henrik Grubbström (Grubba) | | #define LOCK() mixed key__; catch { key__ = lock->lock(); }
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | #define UNLOCK() do { if (key__) destruct(key__); } while(0)
#else /* !constant(create_thread) */
#define LOCK()
#define UNLOCK()
#endif /* constant(create_thread) */
constant READ_BUF_SIZE = 256;
constant CACHE_SIZE_LIMIT = 512;
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | string base;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | object catalog_file;
object data_file;
mapping(string:int) new_entries_cache = ([]);
mapping(string:object) active_objects = ([]);
array(int) index;
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | array(string) index_acc;
int acc_scale;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
int next_offset;
static class QuotaEntry
{
string name;
int data_offset;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | static int usage;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | static int quota;
static void store()
{
LOCK();
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaEntry::store(): Usage for %O is now %O(%O)\n",
name, usage, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
data_file->seek(data_offset);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | data_file->write(sprintf("%4c", usage));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
UNLOCK();
}
static void read()
{
LOCK();
data_file->seek(data_offset);
string s = data_file->read(4);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | usage = 0;
sscanf(s, "%4c", usage);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
01f680 | 1999-06-20 | Henrik Grubbström (Grubba) | | if (usage < 0) {
usage = 0;
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaEntry::read(): Usage for %O is %O(%O)\n",
name, usage, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
UNLOCK();
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | void create(string n, int d_o, int q)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaEntry(%O, %O, %O)\n", n, d_o, q));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
name = n;
data_offset = d_o;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | quota = q;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
read();
}
int check_quota(string uri, int amount)
{
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaEntry::check_quota(%O, %O): usage:%d(%d)\n",
uri, amount, usage, quota));
if (!quota) {
return 0;
}
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
if (amount == 0x7fffffff) {
return 1;
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return(usage + amount <= quota);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
int allocate(string uri, int amount)
{
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaEntry::allocate(%O, %O): usage:%d => %d(%d)\n",
uri, amount, usage, usage + amount, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | usage += amount;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
01f680 | 1999-06-20 | Henrik Grubbström (Grubba) | | if (usage < 0) {
usage = 0;
}
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | store();
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return(usage <= quota);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
int deallocate(string uri, int amount)
{
return(allocate(uri, -amount));
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | int get_usage(string uri)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return usage;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | void set_usage(string uri, int amount)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | usage = amount;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
store();
}
#if !constant(set_weak_flag)
static int refs;
void add_ref()
{
refs++;
}
void free_ref()
{
if (!(--refs)) {
destruct();
}
}
}
static class QuotaProxy
{
static object(QuotaEntry) master;
function(string, int:int) check_quota;
function(string, int:int) allocate;
function(string, int:int) deallocate;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | function(string, int:void) set_usage;
function(string:int) get_usage;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
void create(object(QuotaEntry) m)
{
master = m;
master->add_ref();
check_quota = master->check_quota;
allocate = master->allocate;
deallocate = master->deallocate;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | set_usage = master->set_usage;
get_usage = master->get_usage;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
void destroy()
{
master->free_ref();
}
#endif /* !constant(set_weak_flag) */
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | static object read_entry(int offset, int|void quota)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::read_entry(%O, %O)\n", offset, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
catalog_file->seek(offset);
string data = catalog_file->read(READ_BUF_SIZE);
if (data == "") {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::read_entry(%O, %O): At EOF\n",
offset, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
return 0;
}
int len;
int data_offset;
string key;
sscanf(data[..7], "%4c%4c", len, data_offset);
if (len > sizeof(data)) {
key = data[8..] + catalog_file->read(len - sizeof(data));
len -= 8;
if (sizeof(key) != len) {
error(sprintf("Failed to read catalog entry at offset %d.\n"
"len: %d, sizeof(key):%d\n",
offset, len, sizeof(key)));
}
} else {
key = data[8..len-1];
|
6fa7e8 | 1999-05-14 | Henrik Grubbström (Grubba) | | catalog_file->seek(offset + 8 + sizeof(key));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return QuotaEntry(key, data_offset, quota);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
static object open(string fname, int|void create_new)
{
object f = Stdio.File();
string mode = create_new?"rwc":"rw";
if (!f->open(fname, mode)) {
error(sprintf("Failed to open quota file %O.\n", fname));
}
if (f->try_lock && !f->try_lock()) {
error(sprintf("Failed to lock quota file %O.\n", fname));
}
return(f);
}
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | static void init_index_acc()
{
acc_scale = 1;
if (sizeof(index)) {
int i = sizeof(index)/2;
while (i) {
i /= 4;
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | acc_scale *= 2;
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | }
}
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | index_acc = allocate((sizeof(index) + acc_scale -1)/acc_scale);
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | |
QD_WRITE(sprintf("QuotaDB()::init_index_acc(): "
"sizeof(index):%d, sizeof(index_acc):%d acc_scale:%d\n",
sizeof(index), sizeof(index_acc), acc_scale));
}
|
1a7b00 | 1999-05-14 | Henrik Grubbström (Grubba) | | void rebuild_index()
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | array(string) new_keys = sort(indices(new_entries_cache));
int prev;
array(int) new_index = ({});
foreach(new_keys, string key) {
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::rebuild_index(): key:%O lo:0 hi:%d\n",
key, sizeof(index_acc)));
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | int lo;
int hi = sizeof(index_acc);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (hi) {
do {
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | |
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | int probe = (lo + hi)/2;
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::rebuild_index(): acc: "
"key:%O lo:%d probe:%d hi:%d\n",
key, lo, probe, hi));
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (!index_acc[probe]) {
object e = read_entry(index[probe * acc_scale]);
index_acc[probe] = e->name;
}
if (index_acc[probe] < key) {
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | lo = probe + 1;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | } else if (index_acc[probe] > key) {
hi = probe;
} else {
break;
}
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | } while(lo < hi);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | |
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | if (lo < hi) {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | |
continue;
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | }
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | if (hi) {
hi *= acc_scale;
lo = hi - acc_scale;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | |
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | if (hi > sizeof(index)) {
hi = sizeof(index);
}
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | |
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | | do {
int probe = (lo + hi)/2;
QD_WRITE(sprintf("QuotaDB::rebuild_index(): "
"key:%O lo:%d probe:%d hi:%d\n",
key, lo, probe, hi));
object e = read_entry(index[probe]);
if (e->name < key) {
lo = probe + 1;
} else if (e->name > key) {
hi = probe;
} else {
break;
}
} while (lo < hi);
if (lo < hi) {
continue;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | }
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | }
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | new_index += index[prev..hi-1] + ({ new_entries_cache[key] });
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | prev = hi;
} else {
new_index += ({ new_entries_cache[key] });
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | }
}
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | |
new_index += index[prev..];
QD_WRITE("Index rebuilt.\n");
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | LOCK();
object index_file = open(base + ".index.new", 1);
string to_write = sprintf("%@4c", new_index);
if (index_file->write(to_write) != sizeof(to_write)) {
index_file->close();
rm(base + ".index.new");
} else {
mv(base + ".index.new", base + ".index");
}
index = new_index;
init_index_acc();
UNLOCK();
foreach(new_keys, string key) {
m_delete(new_entries_cache, key);
}
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | static object low_lookup(string key, int quota)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::low_lookup(%O, %O)\n", key, quota));
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | int cat_offset;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | if (!zero_type(cat_offset = new_entries_cache[key])) {
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB::low_lookup(%O, %O): "
"Found in new entries cache.\n", key, quota));
return read_entry(cat_offset, quota);
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | }
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | |
int lo;
int hi = sizeof(index_acc);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (hi) {
do {
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | |
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | int probe = (lo + hi)/2;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB:low_lookup(%O): "
"In acc: lo:%d, probe:%d, hi:%d\n",
key, lo, probe, hi));
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (!index_acc[probe]) {
object e = read_entry(index[probe * acc_scale], quota);
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | |
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | index_acc[probe] = e->name;
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | |
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (key == e->name) {
QD_WRITE(sprintf("QuotaDB:low_lookup(%O): In acc: Found at %d\n",
key, probe * acc_scale));
return e;
}
}
if (index_acc[probe] < key) {
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | lo = probe + 1;
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | } else if (index_acc[probe] > key) {
hi = probe;
} else {
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | QD_WRITE(sprintf("QuotaDB:low_lookup(%O): In acc: Found at %d\n",
key, probe * acc_scale));
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return read_entry(index[probe * acc_scale], quota);
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | }
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | } while(lo < hi);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | if (hi) {
hi *= acc_scale;
lo = hi - acc_scale;
|
8b5f0c | 1999-05-16 | Henrik Grubbström (Grubba) | |
if (hi > sizeof(index)) {
hi = sizeof(index);
}
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | do {
int probe = (lo + hi)/2;
QD_WRITE(sprintf("QuotaDB:low_lookup(%O): lo:%d, probe:%d, hi:%d\n",
key, lo, probe, hi));
object e = read_entry(index[probe], quota);
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | |
|
366b79 | 1999-05-16 | Henrik Grubbström (Grubba) | | if (e->name < key) {
lo = probe + 1;
} else if (e->name > key) {
hi = probe;
} else {
QD_WRITE(sprintf("QuotaDB:low_lookup(%O): Found at %d\n",
key, probe));
return e;
}
} while (lo < hi);
}
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | }
QD_WRITE(sprintf("QuotaDB::low_lookup(%O): Not found\n", key));
return 0;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
object lookup(string key, int quota)
{
QD_WRITE(sprintf("QuotaDB::lookup(%O, %O)\n", key, quota));
LOCK();
object res;
if (res = active_objects[key]) {
QD_WRITE(sprintf("QuotaDB::lookup(%O, %O): User in active objects.\n",
key, quota));
#if constant(set_weak_flag)
return res;
#else /* !constant(set_weak_flag) */
return QuotaProxy(res);
#endif /* constant(set_weak_flag) */
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (res = low_lookup(key, quota)) {
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | active_objects[key] = res;
#if constant(set_weak_flag)
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | return res;
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | #else /* !constant(set_weak_flag) */
return QuotaProxy(res);
#endif /* constant(set_weak_flag) */
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
QD_WRITE(sprintf("QuotaDB::lookup(%O, %O): New user.\n", key, quota));
data_file->seek(-1);
data_file->read(1);
catalog_file->seek(next_offset);
int data_offset = data_file->tell();
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | if (data_file->write(sprintf("%4c", 0)) != 4) {
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | error(sprintf("write() failed for quota data file!\n"));
}
string entry = sprintf("%4c%4c%s", sizeof(key)+8, data_offset, key);
if (catalog_file->write(entry) != sizeof(entry)) {
error(sprintf("write() failed for quota catalog file!\n"));
}
new_entries_cache[key] = next_offset;
next_offset = catalog_file->tell();
if (sizeof(new_entries_cache) > CACHE_SIZE_LIMIT) {
rebuild_index();
}
|
eed714 | 1999-05-12 | Henrik Grubbström (Grubba) | | return low_lookup(key, quota);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | }
void create(string base_name, int|void create_new)
{
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | base = base_name;
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | catalog_file = open(base_name + ".cat", create_new);
data_file = open(base_name + ".data", create_new);
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | object index_file = open(base_name + ".index", 1);
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | |
#if constant(set_weak_flag)
set_weak_flag(active_objects, 1);
#endif /* constant(set_weak_flag) */
array index_st = index_file->stat();
if (!index_st || !sizeof(index_st)) {
error(sprintf("stat() failed for quota index file!\n"));
}
array data_st = data_file->stat();
if (!data_st || !sizeof(data_st)) {
error(sprintf("stat() failed for quota data file!\n"));
}
if (index_st[1] < 0) {
error("quota index file isn't a regular file!\n");
}
if (data_st[1] < 0) {
error("quota data file isn't a regular file!\n");
}
if (data_st[1] < index_st[1]) {
error("quota data file is shorter than the index file!\n");
}
if (index_st[1] & 3) {
error("quota index file has odd length!\n");
}
if (data_st[1] & 3) {
error("quota data file has odd length!\n");
}
int i;
array(string) index_str = index_file->read()/4;
index = allocate(sizeof(index_str));
|
a3e427 | 1999-05-11 | Henrik Grubbström (Grubba) | | if (sizeof(index_str) && (sizeof(index_str[-1]) != 4)) {
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | error("Truncated read of the index file!\n");
}
foreach(index_str, string offset_str) {
int offset;
sscanf(offset_str, "%4c", offset);
index[i++] = offset;
if (offset > next_offset) {
next_offset = offset;
}
}
|
e9857a | 1999-05-08 | Henrik Grubbström (Grubba) | | init_index_acc();
|
ebc988 | 1999-05-06 | Henrik Grubbström (Grubba) | | if (sizeof(index)) {
mixed entry = read_entry(next_offset);
next_offset = catalog_file->tell();
}
if (index_st[1] < data_st[1]) {
while (mixed entry = read_entry(next_offset)) {
new_entries_cache[entry->name] = next_offset;
next_offset = catalog_file->tell();
}
rebuild_index();
}
}
}
|
69e4cd | 2000-03-09 | Martin Stjernholm | |
|
df6c03 | 2000-08-09 | Per Hedbor | | #define CTX()
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | class EScope(string scope)
|
df6c03 | 2000-08-09 | Per Hedbor | | {
void delete( string var )
{
RXML.Context ctx = RXML.get_context( );
ctx->delete_var( var, scope );
}
string name()
{
RXML.Context ctx = RXML.get_context( );
return scope == "_" ? ctx->current_scope() : scope;
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static mixed `[]( string what )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
RXML.Context ctx = RXML.get_context( );
return ctx->get_var( what, scope );
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static mixed `->( string what )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
return `[]( what );
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static mixed `[]=( string what, mixed nval )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
RXML.Context ctx = RXML.get_context( );
ctx->set_var( what, nval, scope );
return nval;
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static mixed `->=( string what, mixed nval )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
return `[]=( what, nval );
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static array(string) _indices( )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
RXML.Context ctx = RXML.get_context( );
return ctx->list_var( scope );
}
|
f35256 | 2000-09-24 | Henrik Grubbström (Grubba) | | static array(string) _values( )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
RXML.Context ctx = RXML.get_context( );
return map( ctx->list_var( scope ), `[] );
}
}
class SRestore
{
mapping osc = ([]);
void destroy()
{
foreach( indices( osc ), string o )
add_constant( o, osc[o] );
add_constant( "roxen", roxenp() );
}
}
SRestore add_scope_constants( string|void name )
{
SRestore res = SRestore();
mapping ac = all_constants();
if(!name) name = "";
|
85a1bb | 2000-08-10 | Per Hedbor | | if( RXML.get_context() )
|
df6c03 | 2000-08-09 | Per Hedbor | | {
|
85a1bb | 2000-08-10 | Per Hedbor | | foreach( RXML.get_context()->list_scopes()|({"_"}), string scope )
{
res->osc[ name+scope ] = ac[ name+scope ];
add_constant( name+scope, EScope( scope ) );
}
|
df6c03 | 2000-08-09 | Per Hedbor | | }
return res;
}
|
703503 | 2000-08-23 | Martin Nilsson | |
mapping(string:string) parser_charref_table =
lambda () {
mapping(string:string) table = ([]);
for (int i = 0; i < sizeof (replace_entities); i++) {
string chref = replace_entities[i];
table[chref[1..sizeof (chref) - 2]] = replace_values[i];
}
return table;
}();
|
f4c4d5 | 2000-08-27 | Martin Stjernholm | |
mapping(string:string) inverse_charref_table =
lambda () {
mapping(string:string) table = ([]);
for (int i = 0; i < sizeof (replace_entities); i++) {
string chref = replace_entities[i];
table[replace_values[i]] = chref[1..sizeof (chref) - 2];
}
return table;
}();
string decode_charref (string chref)
{
if (sizeof (chref) <= 2 || chref[0] != '&' || chref[-1] != ';') return 0;
if (chref[1] != '#') return parser_charref_table[chref[1..sizeof (chref) - 2]];
if ((<'x', 'X'>)[chref[2]]) {
if (sscanf (chref, "&%*2s%x;%*c", int c) == 2) return sprintf ("%c", c);
}
else
if (sscanf (chref, "&%*c%d;%*c", int c) == 2) return sprintf ("%c", c);
return 0;
}
|
425fc6 | 2000-09-21 | Per Hedbor | | string|program safe_compile( string code )
{
program ret;
|
6465b9 | 2000-09-27 | Per Hedbor | | roxenloader.LowErrorContainer ec = roxenloader.LowErrorContainer();
|
425fc6 | 2000-09-21 | Per Hedbor | | roxenloader.push_compile_error_handler( ec );
catch(ret = compile_string( code ));
|
6465b9 | 2000-09-27 | Per Hedbor | | roxenloader.pop_compile_error_handler( );
|
425fc6 | 2000-09-21 | Per Hedbor | | if( !ret ) return ec->get();
return ret;
}
|
f4c4d5 | 2000-08-27 | Martin Stjernholm | | string encode_charref (string char)
|
d3beb0 | 2000-08-27 | Martin Stjernholm | |
|
f4c4d5 | 2000-08-27 | Martin Stjernholm | | {
if (string chref = inverse_charref_table[char]) return "&" + chref + ";";
|
d3beb0 | 2000-08-27 | Martin Stjernholm | | return sprintf ("&#%d;", char[0]);
|
f4c4d5 | 2000-08-27 | Martin Stjernholm | | }
|
703503 | 2000-08-23 | Martin Nilsson | |
|
df6c03 | 2000-08-09 | Per Hedbor | |
|
69e4cd | 2000-03-09 | Martin Stjernholm | |
class ScopeRoxen {
inherit RXML.Scope;
string pike_version=predef::version();
int ssl_strength=0;
#if constant(SSL)
void create() {
ssl_strength=40;
|
c4ee17 | 2000-04-06 | Henrik Grubbström (Grubba) | | #if constant(SSL.constants.CIPHER_des)
|
69e4cd | 2000-03-09 | Martin Stjernholm | | if(SSL.constants.CIPHER_algorithms[SSL.constants.CIPHER_des])
ssl_strength=128;
if(SSL.constants.CIPHER_algorithms[SSL.constants.CIPHER_3des])
ssl_strength=168;
|
c4ee17 | 2000-04-06 | Henrik Grubbström (Grubba) | | #endif /* !constant(SSL.constants.CIPHER_des) */
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
#endif
|
703503 | 2000-08-23 | Martin Nilsson | | mixed `[] (string var, void|RXML.Context c, void|string scope) {
|
69e4cd | 2000-03-09 | Martin Stjernholm | | switch(var)
{
case "uptime":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,1);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return (time(1)-roxenp()->start_time);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "uptime-days":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,3600*2);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return (time(1)-roxenp()->start_time)/3600/24;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "uptime-hours":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,1800);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return (time(1)-roxenp()->start_time)/3600;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "uptime-minutes":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,60);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return (time(1)-roxenp()->start_time)/60;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "hits-per-minute":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,2);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return c->id->conf->requests / ((time(1)-roxenp()->start_time)/60 + 1);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "hits":
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | return c->id->conf->requests;
case "sent-mb":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,10);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | return sprintf("%1.2f",c->id->conf->sent / (1024.0*1024.0));
case "sent":
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | return c->id->conf->sent;
case "sent-per-minute":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,2);
|
dbf991 | 2000-03-19 | Martin Nilsson | | return c->id->conf->sent / ((time(1)-roxenp()->start_time)/60 || 1);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "sent-kbit-per-second":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,2);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | return sprintf("%1.2f",((c->id->conf->sent*8)/1024.0/
|
dbf991 | 2000-03-19 | Martin Nilsson | | (time(1)-roxenp()->start_time || 1)));
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "ssl-strength":
return ssl_strength;
case "pike-version":
return pike_version;
case "version":
|
dbf991 | 2000-03-19 | Martin Nilsson | | return roxenp()->version();
|
88bff1 | 2000-09-12 | Per Hedbor | | case "base-version":
return __roxen_version__;
case "build":
return __roxen_build__;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | case "time":
|
7e9a0b | 2000-09-16 | Per Hedbor | | CACHE(c->id,1);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | return time(1);
case "server":
return c->id->conf->query("MyWorldLocation");
|
9705b9 | 2000-07-02 | Martin Nilsson | | case "domain":
string tmp=c->id->conf->query("MyWorldLocation");
sscanf(tmp, "%*s//%s", tmp);
sscanf(tmp, "%s:", tmp);
sscanf(tmp, "%s/", tmp);
return tmp;
|
703503 | 2000-08-23 | Martin Nilsson | | case "locale":
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
703503 | 2000-08-23 | Martin Nilsson | | return roxenp()->locale->get();
|
b44ce5 | 2000-12-04 | Martin Nilsson | | case "path":
|
21288a | 2000-12-04 | Martin Nilsson | | return c->id->misc->site_prefix_path || "";
|
703503 | 2000-08-23 | Martin Nilsson | | default:
return RXML.nil;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
:: `[] (var, c, scope);
}
array(string) _indices() {
return ({"uptime", "uptime-days", "uptime-hours", "uptime-minutes",
"hits-per-minute", "hits", "sent-mb", "sent",
"sent-per-minute", "sent-kbit-per-second", "ssl-strength",
|
b44ce5 | 2000-12-04 | Martin Nilsson | | "pike-version", "version", "time", "server", "domain",
"locale", "path"});
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
string _sprintf() { return "RXML.Scope(roxen)"; }
}
class ScopePage {
inherit RXML.Scope;
constant converter=(["fgcolor":"fgcolor", "bgcolor":"bgcolor",
"theme-bgcolor":"theme_bgcolor", "theme-fgcolor":"theme_fgcolor",
"theme-language":"theme_language"]);
constant in_defines=aggregate_multiset(@indices(converter));
mixed `[] (string var, void|RXML.Context c, void|string scope) {
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
971ed3 | 2000-03-20 | Martin Stjernholm | | switch (var) {
case "pathinfo": return c->id->misc->path_info;
}
|
69e4cd | 2000-03-09 | Martin Stjernholm | | if(in_defines[var])
return c->id->misc->defines[converter[var]];
if(objectp(c->id->misc->scope_page[var])) return c->id->misc->scope_page[var]->rxml_var_eval(c, var, "page");
return c->id->misc->scope_page[var];
}
mixed `[]= (string var, mixed val, void|RXML.Context c, void|string scope_name) {
|
971ed3 | 2000-03-20 | Martin Stjernholm | | switch (var) {
case "pathinfo": return c->id->misc->path_info = val;
}
|
69e4cd | 2000-03-09 | Martin Stjernholm | | if(in_defines[var])
return c->id->misc->defines[converter[var]]=val;
return c->id->misc->scope_page[var]=val;
}
array(string) _indices(void|RXML.Context c) {
if(!c) return ({});
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | array ind=indices(c->id->misc->scope_page);
foreach(indices(in_defines), string def)
if(c->id->misc->defines[converter[def]]) ind+=({def});
|
a458af | 2000-03-20 | Martin Stjernholm | | return ind + ({"pathinfo"});
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
void m_delete (string var, void|RXML.Context c, void|string scope_name) {
if(!c) return;
|
971ed3 | 2000-03-20 | Martin Stjernholm | | switch (var) {
case "pathinfo":
predef::m_delete (c->id->misc, "pathinfo");
return;
}
|
69e4cd | 2000-03-09 | Martin Stjernholm | | if(in_defines[var]) {
if(var[0..4]=="theme")
predef::m_delete(c->id->misc->defines, converter[var]);
else
::m_delete(var, c, scope_name);
|
971ed3 | 2000-03-20 | Martin Stjernholm | | return;
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
predef::m_delete(c->id->misc->scope_page, var);
}
string _sprintf() { return "RXML.Scope(page)"; }
}
|
703503 | 2000-08-23 | Martin Nilsson | | class ScopeCookie {
inherit RXML.Scope;
|
69e4cd | 2000-03-09 | Martin Stjernholm | |
|
703503 | 2000-08-23 | Martin Nilsson | | mixed `[] (string var, void|RXML.Context c, void|string scope) {
if(!c) return RXML.nil;
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
703503 | 2000-08-23 | Martin Nilsson | | return c->id->cookies[var];
}
mixed `[]= (string var, mixed val, void|RXML.Context c, void|string scope_name) {
if(c && c->id->cookies[var]!=val) {
c->id->cookies[var]=val;
add_http_header(c->id->misc->defines[" _extra_heads"], "Set-Cookie", http_encode_cookie(var)+
"="+http_encode_cookie( (string)(val||"") )+
"; expires="+http_date(time(1)+(3600*24*365*2))+"; path=/");
|
9bf118 | 2000-08-12 | Martin Stjernholm | | }
|
703503 | 2000-08-23 | Martin Nilsson | | return RXML.nil;
}
array(string) _indices(void|RXML.Context c) {
if(!c) return ({});
|
7e9a0b | 2000-09-16 | Per Hedbor | | NOCACHE(c->id);
|
703503 | 2000-08-23 | Martin Nilsson | | return indices(c->id->cookies);
}
void m_delete (string var, void|RXML.Context c, void|string scope_name) {
if(!c || !c->id->cookies[var]) return;
predef::m_delete(c->id->cookies, var);
add_http_header(c->id->misc->defines[" _extra_heads"], "Set-Cookie",
http_encode_cookie(var)+"=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/");
}
string _sprintf() { return "RXML.Scope(Cookie)"; }
}
RXML.Scope scope_roxen=ScopeRoxen();
RXML.Scope scope_page=ScopePage();
RXML.Scope scope_cookie=ScopeCookie();
|
9bf118 | 2000-08-12 | Martin Stjernholm | |
|
3c4c6e | 2000-11-02 | Per Hedbor | | class ScopeModVar
{
class Modules( mapping module, string sname )
{
class ModVars( RoxenModule mod )
{
class Var(object var )
{
inherit RXML.Value;
mixed cast( string type )
{
switch( type )
{
case "string": return (string)var->query();
case "int": return (int)var->query();
case "float": return (float)var->query();
case "array": return (array)var->query();
}
}
mixed rxml_var_eval( RXML.Context ctx, string vn, string scp,
void|RXML.Type type )
{
mixed res = var->query();
if( type )
res = type->encode( res );
return res;
}
}
mixed cast( string type )
{
switch( type )
{
case "string":
return roxenp()->find_module( sname ) ?
roxenp()->find_module( sname )->get_name() : sname;
}
}
array _values()
{
return map( _indices(), `[] );
}
array _indices()
{
mapping m = mod->getvars();
return sort( filter( indices(m),
lambda(string n) {
return m[n]->get_flags()&VAR_PUBLIC;
} ) );
}
mixed `[]( string what )
{
object var;
if( (var = mod->getvar( what )) )
{
if( (var->get_flags() & VAR_PUBLIC) )
return Var( var );
else
RXML.parse_error("The variable "+what+" is not public\n");
} else
RXML.parse_error("The variable "+what+" does not exist\n");
}
}
mixed cast( string type )
{
switch( type )
{
case "string":
return roxenp()->find_module( sname ) ?
roxenp()->find_module( sname )->get_name() : sname;
}
}
array _values()
{
return map( _indices(), `[] );
}
array _indices()
{
return sort(indices( module ));
}
mixed `[]( string what )
{
mixed mod;
if( (mod = (int)what) )
if( (mod = module[ mod-1 ]) )
return ModVars( module[mod-1] );
|
343ee6 | 2000-11-06 | Per Hedbor | |
|
3c4c6e | 2000-11-02 | Per Hedbor | | return ModVars( values( module )[0] )[ what ];
}
}
mixed `[]( string what )
{
if( what == "site" )
return Modules( ([ 0:RXML.get_context()->id->conf ]), "site" );
if( what == "global" )
return Modules( ([ 0:roxenp() ]), "roxen" );
if( !RXML.get_context()->id->conf->modules[ what ] )
RXML.parse_error("The module "+what+" does not exist\n");
return Modules( RXML.get_context()->id->conf->modules[ what ], what );
}
array _values( )
{
return map( _indices(), `[] );
}
array _indices()
{
return ({ "site" }) +
sort(indices(RXML.get_context()->id->conf->modules));
}
}
class FormScope( mapping variables )
{
inherit RXML.Scope;
class AVal( array var, string name )
{
mixed cast( string type )
{
switch( type )
{
case "string":
return var*"\0";
}
}
array _indices()
{
return indices( variables );
}
array _values()
{
return map( _indices(), `[] );
}
mixed `[]=( string index, mixed newval )
{
mixed res;
if( int ind = (int)index )
if( (ind > sizeof( var ))
|| ((ind < 0) && (-ind > sizeof( var ) )) )
RXML.parse_error( "Array not big enough for index %d.\n", ind );
else if( ind < 0 )
|
02919a | 2000-11-03 | Leif Stensson | | var[ind] = newval;
|
3c4c6e | 2000-11-02 | Per Hedbor | | else
|
02919a | 2000-11-03 | Leif Stensson | | var[ind-1] = newval;
|
3c4c6e | 2000-11-02 | Per Hedbor | | else
RXML.parse_error( "Cannot index array with %O\n", ind );
RXML.get_context()->id->variables[name] = ((array(string))var)*"\0";
|
02919a | 2000-11-03 | Leif Stensson | | return newval;
|
3c4c6e | 2000-11-02 | Per Hedbor | | }
mixed `[]( string index )
{
if( int ind = (int)index )
if( (ind > sizeof( var ))
|| ((ind < 0) && (-ind > sizeof( var ) )) )
RXML.parse_error( "Array not big enough for index %d.\n", ind );
else if( ind < 0 )
return var[ind];
else
return var[ind-1];
else
RXML.parse_error( "Cannot index array with %O\n", ind );
}
}
|
8c6fbe | 2000-11-02 | Per Hedbor | | mixed `[]=( string index, mixed newval )
{
variables[ index ] = newval;
}
|
3c4c6e | 2000-11-02 | Per Hedbor | | mixed `[]( string what )
{
mixed q = variables[ what ];
|
d8a2dc | 2000-12-02 | Per Hedbor | | if( !arrayp(q) )
|
9a3dbd | 2000-11-16 | Per Hedbor | | return q;
|
3c4c6e | 2000-11-02 | Per Hedbor | | if( sizeof( q ) == 1 )
return q[0];
return AVal( q, what );
}
array _values( )
{
return map( _indices(), `[] );
}
array _indices()
{
return indices( variables );
}
}
ScopeModVar scope_modvar = ScopeModVar();
|
69e4cd | 2000-03-09 | Martin Stjernholm | | RXML.TagSet entities_tag_set = class
{
inherit RXML.TagSet;
void prepare_context (RXML.Context c) {
c->add_scope("roxen",scope_roxen);
c->id->misc->scope_page=([]);
c->add_scope("page",scope_page);
|
703503 | 2000-08-23 | Martin Nilsson | | c->add_scope("cookie", scope_cookie);
|
3c4c6e | 2000-11-02 | Per Hedbor | | c->add_scope("modvar", scope_modvar);
|
d8a2dc | 2000-12-02 | Per Hedbor | | c->add_scope("form", FormScope( c->id->real_variables) );
|
703503 | 2000-08-23 | Martin Nilsson | | c->add_scope("client", c->id->client_var);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | c->add_scope("var", ([]) );
}
void create (string name)
{
::create (name);
|
7eeec7 | 2000-07-06 | Martin Stjernholm | |
|
9bf118 | 2000-08-12 | Martin Stjernholm | | add_string_entities (parser_charref_table);
|
69e4cd | 2000-03-09 | Martin Stjernholm | | }
} ("entities_tag_set");
|
dbf991 | 2000-03-19 | Martin Nilsson | |
|
b92a1c | 2000-08-14 | Martin Stjernholm | |
|
dbf991 | 2000-03-19 | Martin Nilsson | | constant monthnum=(["Jan":0, "Feb":1, "Mar":2, "Apr":3, "May":4, "Jun":5,
"Jul":6, "Aug":7, "Sep":8, "Oct":9, "Nov":10, "Dec":11,
"jan":0, "feb":1, "mar":2, "apr":3, "may":4, "jun":5,
"jul":6, "aug":7, "sep":8, "oct":9, "nov":10, "dec":11,]);
#define MAX_SINCE_CACHE 16384
static mapping(string:int) since_cache=([ ]);
array(int) parse_since(string date)
{
if(!date || sizeof(date)<14) return({0,-1});
int t=0, length = -1;
#if constant(mktime)
|
f6deda | 2000-07-11 | Martin Nilsson | | string dat=lower_case(date);
sscanf(dat+"; length=", "%*s, %s; length=%d", dat, length);
|
dbf991 | 2000-03-19 | Martin Nilsson | |
if(!(t=since_cache[dat])) {
int day, year = -1, month, hour, minute, second;
string m;
if(sscanf(dat, "%d-%s-%d %d:%d:%d", day, m, year, hour, minute, second)>2)
{
month=monthnum[m];
} else if(dat[2]==',') {
sscanf(dat, "%*s, %d %s %d %d:%d:%d", day, m, year, hour, minute, second);
month=monthnum[m];
} else if(!(int)dat) {
sscanf(dat, "%*[^ ] %s %d %d:%d:%d %d", m, day, hour, minute, second, year);
month=monthnum[m];
} else {
sscanf(dat, "%d %s %d %d:%d:%d", day, m, year, hour, minute, second);
month=monthnum[m];
}
if(year >= 0) {
if (year < 60) {
year += 100;
} else if (year >= 1900) {
year -= 1900;
}
catch {
|
df6c03 | 2000-08-09 | Per Hedbor | | t = mktime(second, minute, hour, day, month, year, 0, 0);
|
dbf991 | 2000-03-19 | Martin Nilsson | | };
} else {
report_debug("Could not parse \""+date+"\" to a time int.");
}
if (sizeof(since_cache) > MAX_SINCE_CACHE)
since_cache = ([]);
since_cache[dat]=t;
}
#endif /* constant(mktime) */
return ({ t, length });
}
int is_modified(string a, int t, void|int len)
{
array vals=parse_since(a);
if(len && len!=vals[1]) return 0;
if(vals[0]<t) return 0;
return 1;
}
int httpdate_to_time(string date)
{
return parse_since(date)[0]||-1;
}
|
31d164 | 2000-03-26 | Martin Nilsson | |
|
3580f5 | 2000-09-03 | Per Hedbor | | void set_cookie( RequestID id,
string name,
string value,
int|void expire_time_delta,
string|void domain,
string|void path )
{
|
52049e | 2000-12-04 | Stefan Wallström | | if( expire_time_delta == -1 )
|
3580f5 | 2000-09-03 | Per Hedbor | | expire_time_delta = (3600*(24*365*5));
string cookie = (http_encode_cookie( name )+"="+
http_encode_cookie( value ));
if( expire_time_delta )
cookie += "; expires="+http_date( expire_time_delta+time(1) );
if( domain ) cookie += "; domain="+http_encode_cookie( domain );
if( path ) cookie += "; path="+http_encode_cookie( path );
if(!id->misc->moreheads)
id->misc->moreheads = ([]);
add_http_header( id->misc->moreheads, "Set-Cookie",cookie );
}
void remove_cookie( RequestID id,
string name,
string value,
string|void domain,
string|void path )
{
set_cookie( id, name, value, -time(1), domain, path );
}
|
c9dd7f | 2000-11-21 | Per Hedbor | | void add_cache_stat_callback( RequestID id, string file, int mtime )
{
while( id->misc->orig )
id = id->misc->orig;
if( !id->misc->_cachecallbacks ) return;
id->misc->_cachecallbacks += ({ lambda( RequestID id, object key ) {
Stat st = file_stat( file );
if( !st || (st[ST_MTIME] != mtime) )
{
destruct( key );
return 0;
}
return 1;
} });
}
|
c3c632 | 2000-09-20 | Per Hedbor | | void add_cache_callback( RequestID id,function(RequestID,object:int) callback )
|
a45647 | 2000-08-31 | Per Hedbor | |
|
c3c632 | 2000-09-20 | Per Hedbor | |
|
a45647 | 2000-08-31 | Per Hedbor | | {
while( id->misc->orig )
id = id->misc->orig;
|
129ed7 | 2000-09-25 | Per Hedbor | | if( !id->misc->_cachecallbacks ) return;
|
a45647 | 2000-08-31 | Per Hedbor | | id->misc->_cachecallbacks |= ({ callback });
}
|
129ed7 | 2000-09-25 | Per Hedbor | | string get_server_url(Configuration c)
{
|
31d164 | 2000-03-26 | Martin Nilsson | | string url=c->query("MyWorldLocation");
if(stringp(url) && sizeof(url)) return url;
array(string) urls=c->query("URLs");
return get_world(urls);
}
string get_world(array(string) urls) {
if(!sizeof(urls)) return 0;
string url=urls[0];
foreach( ({"http:","fhttp:","https:","ftp:"}), string p)
foreach(urls, string u)
if(u[0..sizeof(p)-1]==p) {
url=u;
break;
}
|
f70aa7 | 2000-03-28 | Martin Nilsson | | string protocol, server, path="";
|
31d164 | 2000-03-26 | Martin Nilsson | | int port;
if(sscanf(url, "%s://%s:%d/%s", protocol, server, port, path)!=4 &&
|
f70aa7 | 2000-03-28 | Martin Nilsson | | sscanf(url, "%s://%s:%d", protocol, server, port)!=3 &&
sscanf(url, "%s://%s/%s", protocol, server, path)!=3 &&
sscanf(url, "%s://%s", protocol, server)!=2 )
|
31d164 | 2000-03-26 | Martin Nilsson | | return 0;
if(protocol=="fhttp") protocol="http";
array hosts=({ gethostname() }), dns;
catch(dns=Protocols.DNS.client()->gethostbyname(hosts[0]));
if(dns && sizeof(dns))
hosts+=dns[2]+dns[1];
foreach(hosts, string host)
if(glob(server, host)) {
server=host;
break;
}
if(port) return sprintf("%s://%s:%d/%s", protocol, server, port, path);
return sprintf("%s://%s/%s", protocol, server, path);
}
|
c16622 | 2000-08-09 | Per Hedbor | |
|
b92a1c | 2000-08-14 | Martin Stjernholm | | RoxenModule get_owning_module (object|function thing)
{
|
566c07 | 2000-11-02 | Per Hedbor | | if (functionp (thing))
thing = function_object (thing);
if (objectp (thing))
{
if (thing->is_module)
return thing;
object o = [object]thing;
while (object parent =
functionp (object_program (o)) &&
function_object (object_program (o)))
{
|
b92a1c | 2000-08-14 | Martin Stjernholm | |
|
566c07 | 2000-11-02 | Per Hedbor | | if (parent->is_module)
return parent;
o = parent;
|
b92a1c | 2000-08-14 | Martin Stjernholm | | }
|
566c07 | 2000-11-02 | Per Hedbor | |
if( thing->_do_return )
return get_owning_module( thing->_do_return );
|
b92a1c | 2000-08-14 | Martin Stjernholm | | }
return 0;
}
Configuration get_owning_config (object|function thing)
{
if (RoxenModule mod = get_owning_module (thing))
return mod->my_configuration();
if (functionp (thing)) thing = function_object (thing);
if (objectp (thing)) {
if (thing->is_configuration) return thing;
if (object parent =
functionp (object_program (thing)) &&
function_object (object_program (thing))) {
if (parent->is_configuration) return parent;
}
}
return 0;
}
#ifdef REQUEST_TRACE
|
acc6dd | 2000-08-15 | Martin Stjernholm | | static string trace_msg (RequestID id, string msg, string name)
|
b92a1c | 2000-08-14 | Martin Stjernholm | | {
|
acc6dd | 2000-08-15 | Martin Stjernholm | | msg = html_decode_string (
|
b92a1c | 2000-08-14 | Martin Stjernholm | | Parser.HTML()->_set_tag_callback (lambda (object p, string s) {return "";})->
finish (msg)->read());
|
acc6dd | 2000-08-15 | Martin Stjernholm | | array(string) lines = msg / "\n";
if (lines[-1] == "") lines = lines[..sizeof (lines) - 2];
if (sizeof (lines))
report_debug ("%s%s%-40s %s\n",
map (lines[..sizeof (lines) - 2],
lambda (string s) {
return sprintf ("%s%*s%s\n", id->misc->trace_id_prefix,
id->misc->trace_level + 1, "", s);
}) * "",
id->misc->trace_id_prefix,
sprintf ("%*s%s", id->misc->trace_level + 1, "", lines[-1]),
name);
}
void trace_enter (RequestID id, string msg, object|function thing)
{
if (!id->misc->trace_level) {
|
f4c4d5 | 2000-08-27 | Martin Stjernholm | | id->misc->trace_id_prefix = ({"%%", "##", "§§", "**", "@@", "$$", "¤¤"})[
|
acc6dd | 2000-08-15 | Martin Stjernholm | | all_constants()->id_trace_level_rotate_counter++ % 7];
report_debug ("%s%s Request handled by: %O\n",
id->misc->trace_id_prefix, id->misc->trace_id_prefix[..0],
id->conf);
}
|
b92a1c | 2000-08-14 | Martin Stjernholm | | string name;
if (thing) {
name = get_modfullname (get_owning_module (thing));
if (name)
name = "mod: " + html_decode_string (
Parser.HTML()->_set_tag_callback (lambda (object p, string s) {return "";})->
finish (name)->read());
else if (Configuration conf = get_owning_config (thing))
name = "conf: " + conf->query_name();
|
c7fb94 | 2000-09-05 | Martin Stjernholm | | else
|
b92a1c | 2000-08-14 | Martin Stjernholm | | name = sprintf ("obj: %O", thing);
}
else name = "";
|
acc6dd | 2000-08-15 | Martin Stjernholm | | trace_msg (id, msg, name);
|
b92a1c | 2000-08-14 | Martin Stjernholm | | id->misc->trace_level++;
if(function(string,mixed ...:void) _trace_enter =
[function(string,mixed ...:void)]([mapping(string:mixed)]id->misc)->trace_enter)
_trace_enter (msg, thing);
}
void trace_leave (RequestID id, string desc)
{
if (id->misc->trace_level) id->misc->trace_level--;
|
acc6dd | 2000-08-15 | Martin Stjernholm | | if (sizeof (desc)) trace_msg (id, desc, "");
|
b92a1c | 2000-08-14 | Martin Stjernholm | |
if(function(string:void) _trace_leave =
[function(string:void)]([mapping(string:mixed)]id->misc)->trace_leave)
_trace_leave (desc);
}
|
c16622 | 2000-08-09 | Per Hedbor | | #endif
|