ef78e4 | 2000-08-01 | Leif Stensson | | #include <module.h>
inherit "module";
inherit "roxenlib";
|
2304b9 | 2000-12-18 | Leif Stensson | |
|
ef78e4 | 2000-08-01 | Leif Stensson | |
string cvs_version =
|
bfe4e8 | 2001-01-12 | Leif Stensson | | "$Id: perl.pike,v 2.17 2001/01/12 16:55:48 leif Exp $";
|
ef78e4 | 2000-08-01 | Leif Stensson | |
|
2304b9 | 2000-12-18 | Leif Stensson | | constant module_type = MODULE_FILE_EXTENSION | MODULE_TAG;
|
ef78e4 | 2000-08-01 | Leif Stensson | |
constant module_name = "Perl support";
constant module_doc =
|
2304b9 | 2000-12-18 | Leif Stensson | | "This module provides a faster way of running Perl scripts with Roxen. "
|
ef78e4 | 2000-08-01 | Leif Stensson | | "The module also optionally provides a <perl>..</perl> "
"container to run Perl code from inside RXML pages.";
static string recent_error = 0;
static int parsed_tags = 0, script_calls = 0, script_errors = 0;
|
d4c732 | 2000-08-17 | Leif Stensson | | static mapping handler_settings = ([ ]);
|
ef78e4 | 2000-08-01 | Leif Stensson | | constant thread_safe = 1;
#ifdef THREADS
static object mutex = Thread.Mutex();
#endif
void create()
{
defvar("extensions", ({ "pl", "perl" }), "Extensions", TYPE_STRING_LIST,
"List of URL extensions that should be taken to indicate that the "
"document is a Perl script.");
#if 0
defvar("libdir", "./perl", "Roxen Perl Directory", TYPE_DIR,
"This is the name of a directory with Roxen-related Perl stuff. It "
"should normally point to `perl' in the Roxen server directory, "
"but you may want to point it elsewhere if you want to modify the "
"code.");
#endif
defvar("showbacktrace", 0, "Show Backtraces", TYPE_FLAG,
"This setting decides whether to deliver a backtrace in the document "
"if an error is caught while a script runs.");
defvar("tagenable", 0, "Enable Perl Tag", TYPE_FLAG,
"This setting decides whether to enable parsing of Perl code in "
"RXML pages, in <perl>..</perl> containers.");
defvar("scriptout", "HTML", "Script output", TYPE_MULTIPLE_STRING,
"How to treat script output. HTML means treat it as a plain HTML "
"document. RXML is similar, but passes it through the RXML parser "
"before returning it to the client. HTTP is the traditional CGI "
"output style, where the script is responsible for producing the "
"HTTP headers before the document, as well as the main document "
"data.",
({ "HTML", "RXML", "HTTP" })
);
defvar("rxmltag", 0, "RXML-parse tag results", TYPE_FLAG,
"Allow RXML parsing of tag results.");
|
2304b9 | 2000-12-18 | Leif Stensson | | defvar("helper",
#if constant(system.NetWkstaUserEnum)
|
bfe4e8 | 2001-01-12 | Leif Stensson | | "perl/bin/ntperl.pl",
|
2304b9 | 2000-12-18 | Leif Stensson | | #else
"perl/bin/perlrun",
#endif
"Perl Helper", TYPE_DIR,
"Path to the Perl helper program used to start Perl subprocesses.");
|
ef78e4 | 2000-08-01 | Leif Stensson | |
defvar("parallel", 2, "Parallel scripts", TYPE_MULTIPLE_INT,
"Number of scripts/tags that may be evaluated in parallel. Don't set "
"this higher than necessary, since it may cause the server to block. "
"The default for this setting is 2.",
({ 1, 2, 3, 4, 5 }) );
|
d4c732 | 2000-08-17 | Leif Stensson | |
|
42b293 | 2000-08-23 | Leif Stensson | | #if constant(getpwnam)
|
d4c732 | 2000-08-17 | Leif Stensson | | defvar("identity", "nobody:*", "Run Perl as...", TYPE_STRING,
"User and group to run Perl scripts and tags as. The default for "
"this option is `nobody:*'. Note that Roxen can't change user ID "
|
ba1c9e | 2000-08-22 | Leif Stensson | | "unless it has sufficient permissions to do so. `*' means `use "
"same as Roxen'.");
#endif
|
ef78e4 | 2000-08-01 | Leif Stensson | | }
string status()
{ string s = "<b>Script calls</b>: " + script_calls + " <br />\n" +
"<b>Script errors</b>: " + script_errors + " <br />\n" +
"<b>Parsed tags</b>: " + parsed_tags + " <br />\n";
|
42b293 | 2000-08-23 | Leif Stensson | | #if constant(getpwnam)
|
d4c732 | 2000-08-17 | Leif Stensson | | if (handler_settings->set_uid)
s += sprintf("<b>Subprocess UID</b>: set uid=%O <br />\n",
handler_settings->set_uid);
else
s += "<b>Subprocess UID</b>: same as Roxen<br />\n";
|
ba1c9e | 2000-08-22 | Leif Stensson | | #endif
|
d4c732 | 2000-08-17 | Leif Stensson | |
s += "<b>Helper script</b>: ";
|
2304b9 | 2000-12-18 | Leif Stensson | | if (Stdio.File(QUERY(helper), "r"))
s += "found: " + QUERY(helper)+" <br />\n";
|
d4c732 | 2000-08-17 | Leif Stensson | | else
s += "not found.<br />\n";
|
ef78e4 | 2000-08-01 | Leif Stensson | | if (recent_error)
s += "<b>Most recent error</b>: " + recent_error + " <br />\n";
return s;
}
|
d4c732 | 2000-08-17 | Leif Stensson | | static object gethandler()
|
2304b9 | 2000-12-18 | Leif Stensson | | { return ExtScript.getscripthandler(QUERY(helper),
|
d4c732 | 2000-08-17 | Leif Stensson | | QUERY(parallel), handler_settings);
}
static void fix_settings()
{
string u, g;
mapping s = ([ ]);
|
42b293 | 2000-08-23 | Leif Stensson | | #if constant(getpwnam)
|
d4c732 | 2000-08-17 | Leif Stensson | | if (sscanf(QUERY(identity), "%s:%s", u, g) == 2)
{
array ua = getpwnam(u), ga = getgrnam(g);
if (!ua) ua = getpwuid((int) u);
if (!ga) ga = getgrgid((int) g);
if (ua) s->set_uid = ua[2];
if (ga) s->set_gid = ga[2];
}
|
ba1c9e | 2000-08-22 | Leif Stensson | | #endif
|
d4c732 | 2000-08-17 | Leif Stensson | |
handler_settings = s;
}
|
ef78e4 | 2000-08-01 | Leif Stensson | | static void periodic()
|
d4c732 | 2000-08-17 | Leif Stensson | | {
fix_settings();
ExtScript.periodic_cleanup();
|
ef78e4 | 2000-08-01 | Leif Stensson | | call_out(periodic, 900);
}
void start()
|
d4c732 | 2000-08-17 | Leif Stensson | | { fix_settings();
call_out(periodic, 900);
|
ef78e4 | 2000-08-01 | Leif Stensson | | }
mixed handle_file_extension(Stdio.File file, string ext, object id)
|
d4c732 | 2000-08-17 | Leif Stensson | | { object h = gethandler();
|
ef78e4 | 2000-08-01 | Leif Stensson | |
if (id->realfile && stringp(id->realfile))
{ array result;
|
d4c732 | 2000-08-17 | Leif Stensson | | NOCACHE();
|
ef78e4 | 2000-08-01 | Leif Stensson | | if (!h) return http_string_answer("<h1>Script support failed.</h1>");
mixed bt = catch (result = h->run(id->realfile, id));
++script_calls;
if (bt)
{ ++script_errors;
|
d4c732 | 2000-08-17 | Leif Stensson | | report_error("Perl script `" + id->realfile + "' failed.\n");
|
ef78e4 | 2000-08-01 | Leif Stensson | | if (QUERY(showbacktrace))
return http_string_answer("<h1>Script Error!</h1>\n<pre>" +
describe_backtrace(bt) + "\n</pre>");
else
return http_string_answer("<h1>Script Error!</h1>");
}
else if (sizeof(result) > 1)
{ string r = result[1];
if (r == "") r = " ";
if (!stringp(r)) r = "(not a string)";
switch (QUERY(scriptout))
{ case "RXML":
return http_rxml_answer(r, id);
case "HTML":
return http_string_answer(r);
case "HTTP":
id->connection()->write("HTTP/1.0 200 OK\r\n");
id->connection()->write(r);
id->connection()->close();
return http_pipe_in_progress();
default:
return http_string_answer("SCRIPT ERROR: "
"bad output mode configured.\n");
}
}
else
{ return http_string_answer(sprintf("RESULT: %O", result));
}
}
return http_string_answer("FOO!");
return 0;
}
constant simpletag_perl_flags = 0;
mixed simpletag_perl(string tag, mapping attr, string contents, object id,
RXML.Frame frame)
{
if (!QUERY(tagenable))
RXML.run_error("<perl>...</perl> tag not enabled in this server.");
|
d4c732 | 2000-08-17 | Leif Stensson | | object h = gethandler();
|
ef78e4 | 2000-08-01 | Leif Stensson | |
if (!h)
RXML.run_error("Perl tag support unavailable.");
|
d4c732 | 2000-08-17 | Leif Stensson | | NOCACHE();
|
ef78e4 | 2000-08-01 | Leif Stensson | | array result;
mixed bt = catch (result = h->eval(contents, id));
++parsed_tags;
if (bt)
{
werror("Perl tag backtrace:\n" + describe_backtrace(bt) + "\n");
RXML.run_error("Perl tag");
}
else if (sizeof(result) > 1)
{ if (result[0] < 0 || !stringp(result[1]))
return "SCRIPT ERROR: " + sprintf("%O", result[1]);
else if (QUERY(rxmltag))
{
frame->result_type = frame->result_type(RXML.PXml);
return parse_rxml(result[1], id);
}
else
return result[1];
}
else
return sprintf("SCRIPT ERROR: bad result: %O", result);
return "<b>(No perl tag support?)</b>";
}
|
2db373 | 2000-08-08 | Leif Stensson | | mixed simple_pi_tag_perl(string tag, mapping attr, string contents, object id,
RXML.Frame frame)
|
d4c732 | 2000-08-17 | Leif Stensson | | {
return simpletag_perl(tag, attr, contents, id, frame);
|
2db373 | 2000-08-08 | Leif Stensson | | }
|
ef78e4 | 2000-08-01 | Leif Stensson | | array(string) query_file_extensions()
|
d4c732 | 2000-08-17 | Leif Stensson | | {
return QUERY(extensions);
|
ef78e4 | 2000-08-01 | Leif Stensson | | }
|
f8dd6d | 2000-09-18 | Kenneth Johansson | | TAGDOCUMENTATION;
#ifdef manual
constant tagdoc=([
|
523da0 | 2000-11-09 | Kenneth Johansson | | "?perl":#"<desc pi='pi'><p><short hide='hide'>
|
3debdf | 2000-09-20 | Kenneth Johansson | | Perl processing instruction tag.</short>This processing intruction
|
190c06 | 2000-11-03 | Kenneth Johansson | | tag allows for evaluating Perl code directly in the document.</p>
|
ef78e4 | 2000-08-01 | Leif Stensson | |
|
f8dd6d | 2000-09-18 | Kenneth Johansson | | <p>Note: Read the installation and configuration documentation in the
Administration manual to set up the Perl support properly. If the
correct parameters are not set the Perl code might not work properly
or security issues might arise.</p>
|
ef78e4 | 2000-08-01 | Leif Stensson | |
|
94bc9d | 2000-10-13 | Kenneth Johansson | | <p>There is also a <tag>perl</tag>...<tag>/perl</tag> container tag
|
f8dd6d | 2000-09-18 | Kenneth Johansson | | available.</p>
</desc>",
]);
#endif
|
ef78e4 | 2000-08-01 | Leif Stensson | |
|