From 275af6c51676c241754d87b2efeb9d964143715f Mon Sep 17 00:00:00 2001 From: tomas Date: Wed, 15 Dec 2004 17:25:50 +0000 Subject: [PATCH] Inlude patched XML_RPC extension into LiveSupport CVS. --- .../modules/storageServer/var/Transport.php | 4 +- .../storageServer/var/xmlrpc/XML/RPC.php | 1190 +++++++++++++++++ .../var/xmlrpc/XML/RPC/Server.php | 310 +++++ .../storageServer/var/xmlrpc/xrLocStor.php | 4 +- 4 files changed, 1504 insertions(+), 4 deletions(-) create mode 100644 livesupport/modules/storageServer/var/xmlrpc/XML/RPC.php create mode 100644 livesupport/modules/storageServer/var/xmlrpc/XML/RPC/Server.php diff --git a/livesupport/modules/storageServer/var/Transport.php b/livesupport/modules/storageServer/var/Transport.php index 9fbfefbd8..4ee7b402a 100644 --- a/livesupport/modules/storageServer/var/Transport.php +++ b/livesupport/modules/storageServer/var/Transport.php @@ -23,11 +23,11 @@ Author : $Author: tomas $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/Transport.php,v $ ------------------------------------------------------------------------------*/ -include_once "xmlrpc/xmlrpc.inc"; +include_once "xmlrpc/XML/RPC.php"; /** * Class for handling file tranport between StorageServer and ArchiveServer
diff --git a/livesupport/modules/storageServer/var/xmlrpc/XML/RPC.php b/livesupport/modules/storageServer/var/xmlrpc/XML/RPC.php new file mode 100644 index 000000000..f5db37b91 --- /dev/null +++ b/livesupport/modules/storageServer/var/xmlrpc/XML/RPC.php @@ -0,0 +1,1190 @@ + +// $Id: RPC.php,v 1.1 2004/12/15 17:25:50 tomas Exp $ + +// License is granted to use or modify this software ("XML-RPC for PHP") +// for commercial or non-commercial use provided the copyright of the author +// is preserved in any distributed or derivative work. + +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Adapted to PEAR standards by Stig S�her Bakken and +// Martin Jansen +// /* $id$ */ + +if (!function_exists('xml_parser_create')) { +// Win 32 fix. From: "Leo West" + if ($WINDIR) { + dl("php_xml.dll"); + } else { + dl("xml.so"); + } +} + +define('XML_RPC_ERROR_INVALID_TYPE', 101); +define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102); +define('XML_RPC_ERROR_CONNECTION_FAILED', 103); +define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104); + +$GLOBALS['XML_RPC_I4'] = "i4"; +$GLOBALS['XML_RPC_Int'] = "int"; +$GLOBALS['XML_RPC_Boolean'] = "boolean"; +$GLOBALS['XML_RPC_Double'] = "double"; +$GLOBALS['XML_RPC_String'] = "string"; +$GLOBALS['XML_RPC_DateTime'] = "dateTime.iso8601"; +$GLOBALS['XML_RPC_Base64'] = "base64"; +$GLOBALS['XML_RPC_Array'] = "array"; +$GLOBALS['XML_RPC_Struct'] = "struct"; + +$GLOBALS['XML_RPC_Types'] = array($GLOBALS['XML_RPC_I4'] => 1, + $GLOBALS['XML_RPC_Int'] => 1, + $GLOBALS['XML_RPC_Boolean'] => 1, + $GLOBALS['XML_RPC_String'] => 1, + $GLOBALS['XML_RPC_Double'] => 1, + $GLOBALS['XML_RPC_DateTime'] => 1, + $GLOBALS['XML_RPC_Base64'] => 1, + $GLOBALS['XML_RPC_Array'] => 2, + $GLOBALS['XML_RPC_Struct'] => 3); + +$GLOBALS['XML_RPC_entities'] = array("quot" => '"', + "amp" => "&", + "lt" => "<", + "gt" => ">", + "apos" => "'"); + +$GLOBALS['XML_RPC_err']["unknown_method"] = 1; +$GLOBALS['XML_RPC_str']["unknown_method"] = "Unknown method"; +$GLOBALS['XML_RPC_err']["invalid_return"] = 2; +$GLOBALS['XML_RPC_str']["invalid_return"] = "Invalid return payload: enabling debugging to examine incoming payload"; +$GLOBALS['XML_RPC_err']["incorrect_params"] = 3; +$GLOBALS['XML_RPC_str']["incorrect_params"] = "Incorrect parameters passed to method"; +$GLOBALS['XML_RPC_err']["introspect_unknown"] = 4; +$GLOBALS['XML_RPC_str']["introspect_unknown"] = "Can't introspect: method unknown"; +$GLOBALS['XML_RPC_err']["http_error"] = 5; +$GLOBALS['XML_RPC_str']["http_error"] = "Didn't receive 200 OK from remote server."; + +$GLOBALS['XML_RPC_defencoding'] = "UTF-8"; + +// let user errors start at 800 +$GLOBALS['XML_RPC_erruser'] = 800; + +// let XML parse errors start at 100 +$GLOBALS['XML_RPC_errxml'] = 100; + +// formulate backslashes for escaping regexp +$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92); + +$GLOBALS['XML_RPC_twoslash'] = $GLOBALS['XML_RPC_backslash'] . $GLOBALS['XML_RPC_backslash']; +$GLOBALS['XML_RPC_twoslash'] = "2SLS"; + +// used to store state during parsing +// quick explanation of components: +// st - used to build up a string for evaluation +// ac - used to accumulate values +// qt - used to decide if quotes are needed for evaluation +// cm - used to denote struct or array (comma needed) +// isf - used to indicate a fault +// lv - used to indicate "looking for a value": implements +// the logic to allow values with no types to be strings +// params - used to store parameters in method calls +// method - used to store method name + +$GLOBALS['XML_RPC_xh'] = array(); + +function XML_RPC_entity_decode($string) +{ + $top = split("&", $string); + $op = ""; + $i = 0; + while($i < sizeof($top)) { + if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs)) { + $op .= ereg_replace("^[#a-zA-Z0-9]+;", + XML_RPC_lookup_entity($regs[1]), + $top[$i]); + } else { + if ($i == 0) { + $op = $top[$i]; + } else { + $op .= "&" . $top[$i]; + } + } + + $i++; + } + return $op; +} + + +function XML_RPC_lookup_entity($ent) +{ + global $XML_RPC_entities; + + if ($XML_RPC_entities[strtolower($ent)]) { + return $XML_RPC_entities[strtolower($ent)]; + } + + if (ereg("^#([0-9]+)$", $ent, $regs)) { + return chr($regs[1]); + } + + return "?"; +} + + +function XML_RPC_se($parser, $name, $attrs) +{ + global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String; + + switch ($name) { + case "STRUCT": + case "ARRAY": + $XML_RPC_xh[$parser]['st'] .= "array("; + $XML_RPC_xh[$parser]['cm']++; + // this last line turns quoting off + // this means if we get an empty array we'll + // simply get a bit of whitespace in the eval + $XML_RPC_xh[$parser]['qt'] = 0; + break; + + case "NAME": + $XML_RPC_xh[$parser]['st'] .= "'"; + $XML_RPC_xh[$parser]['ac'] = ""; + break; + + case "FAULT": + $XML_RPC_xh[$parser]['isf'] = 1; + break; + + case "PARAM": + $XML_RPC_xh[$parser]['st'] = ""; + break; + + case "VALUE": + $XML_RPC_xh[$parser]['st'] .= "new XML_RPC_Value("; + $XML_RPC_xh[$parser]['lv'] = 1; + $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String; + $XML_RPC_xh[$parser]['ac'] = ""; + $XML_RPC_xh[$parser]['qt'] = 0; + // look for a value: if this is still 1 by the + // time we reach the first data segment then the type is string + // by implication and we need to add in a quote + break; + + case "I4": + case "INT": + case "STRING": + case "BOOLEAN": + case "DOUBLE": + case "DATETIME.ISO8601": + case "BASE64": + $XML_RPC_xh[$parser]['ac'] = ""; // reset the accumulator + + if ($name == "DATETIME.ISO8601" || $name == "STRING") { + $XML_RPC_xh[$parser]['qt'] = 1; + + if ($name == "DATETIME.ISO8601") { + $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime; + } + + } elseif ($name == "BASE64") { + $XML_RPC_xh[$parser]['qt'] = 2; + } else { + // No quoting is required here -- but + // at the end of the element we must check + // for data format errors. + $XML_RPC_xh[$parser]['qt'] = 0; + } + break; + + case "MEMBER": + case "METHODNAME": + $XML_RPC_xh[$parser]['ac'] = ""; + break; + + default: + break; + } + + if ($name!="VALUE") { + $XML_RPC_xh[$parser]['lv'] = 0; + } +} + + +function XML_RPC_ee($parser, $name) +{ + global $XML_RPC_xh,$XML_RPC_Types,$XML_RPC_String; + + switch ($name) { + case "STRUCT": + case "ARRAY": + if ($XML_RPC_xh[$parser]['cm'] && substr($XML_RPC_xh[$parser]['st'], -1) == ',') { + $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'],0,-1); + } + + $XML_RPC_xh[$parser]['st'] .= ")"; + $XML_RPC_xh[$parser]['vt'] = strtolower($name); + $XML_RPC_xh[$parser]['cm']--; + break; + + case "NAME": + $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . "' => "; + break; + + case "BOOLEAN": + // special case here: we translate boolean 1 or 0 into PHP + // constants true or false + if ($XML_RPC_xh[$parser]['ac'] == '1') { + $XML_RPC_xh[$parser]['ac'] = "true"; + } else { + $XML_RPC_xh[$parser]['ac'] = "false"; + } + + $XML_RPC_xh[$parser]['vt'] = strtolower($name); + // Drop through intentionally. + + case "I4": + case "INT": + case "STRING": + case "DOUBLE": + case "DATETIME.ISO8601": + case "BASE64": + if ($XML_RPC_xh[$parser]['qt'] == 1) { + // we use double quotes rather than single so backslashification works OK + $XML_RPC_xh[$parser]['st'] .= "\"" . $XML_RPC_xh[$parser]['ac'] . "\""; + } elseif ($XML_RPC_xh[$parser]['qt'] == 2) { + $XML_RPC_xh[$parser]['st'] .= "base64_decode('" . $XML_RPC_xh[$parser]['ac'] . "')"; + } elseif ($name=="BOOLEAN") { + $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac']; + } else { + // we have an I4, INT or a DOUBLE + // we must check that only 0123456789-. are characters here + if (!ereg("^\-?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) { + $this->raiseError("Non-numeric value recieved in INT or DOUBLE", XML_RPC_ERROR_NON_NUMERIC_FOUND); + $XML_RPC_xh[$parser]['st'] .= "ERROR_NON_NUMERIC_FOUND"; + } else { + // it's ok, add it on + $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac']; + } + } + + $XML_RPC_xh[$parser]['ac'] = ""; + $XML_RPC_xh[$parser]['qt'] = 0; + $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value + break; + + case "VALUE": + // deal with a string value + if (strlen($XML_RPC_xh[$parser]['ac']) > 0 && + $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) { + + $XML_RPC_xh[$parser]['st'] .= "\"" . $XML_RPC_xh[$parser]['ac'] . "\""; + } + + // This if () detects if no scalar was inside + // and pads an empty "". + if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') { + $XML_RPC_xh[$parser]['st'] .= '""'; + } + $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')"; + if ($XML_RPC_xh[$parser]['cm']) { + $XML_RPC_xh[$parser]['st'] .= ","; + } + break; + + case "MEMBER": + $XML_RPC_xh[$parser]['ac'] = ""; + $XML_RPC_xh[$parser]['qt'] = 0; + break; + + case "DATA": + $XML_RPC_xh[$parser]['ac'] = ""; + $XML_RPC_xh[$parser]['qt'] = 0; + break; + + case "PARAM": + $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st']; + break; + + case "METHODNAME": + $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", "", $XML_RPC_xh[$parser]['ac']); + break; + + case "BOOLEAN": + // special case here: we translate boolean 1 or 0 into PHP + // constants true or false + if ($XML_RPC_xh[$parser]['ac'] == '1') { + $XML_RPC_xh[$parser]['ac'] = "true"; + } else { + $XML_RPC_xh[$parser]['ac'] = "false"; + } + + $XML_RPC_xh[$parser]['vt'] = strtolower($name); + break; + + default: + break; + } + + // if it's a valid type name, set the type + if (isset($XML_RPC_Types[strtolower($name)])) { + $XML_RPC_xh[$parser]['vt'] = strtolower($name); + } +} + + +function XML_RPC_cd($parser, $data) +{ + global $XML_RPC_xh, $XML_RPC_backslash; + + if ($XML_RPC_xh[$parser]['lv'] != 3) { + // "lookforvalue==3" means that we've found an entire value + // and should discard any further character data + + if ($XML_RPC_xh[$parser]['lv'] == 1) { + // if we've found text and we're just in a then + // turn quoting on, as this will be a string + $XML_RPC_xh[$parser]['qt'] = 1; + // and say we've found a value + $XML_RPC_xh[$parser]['lv'] = 2; + } + + // replace characters that eval would + // do special things with + if (isset($XML_RPC_xh[$parser]['ac'])) { + $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$', + str_replace('"', '\"', str_replace(chr(92), + $XML_RPC_backslash, $data))); + } else { + $XML_RPC_xh[$parser]['ac'] = ''; + } + } +} + + +function XML_RPC_dh($parser, $data) +{ + global $XML_RPC_xh; + + if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { + if ($XML_RPC_xh[$parser]['lv'] == 1) { + $XML_RPC_xh[$parser]['qt'] = 1; + $XML_RPC_xh[$parser]['lv'] = 2; + } + $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$', + str_replace('"', '\"', str_replace(chr(92), + $XML_RPC_backslash, $data))); + } +} + +/** + * Base class + * + * This class provides common functions for all of the XML_RPC classes. + */ +class XML_RPC_Base { + function raiseError($msg, $code) + { + include_once 'PEAR.php'; + PEAR::raiseError(get_class($this) . ": " . $msg, $code); + } +} + +class XML_RPC_Client extends XML_RPC_Base { + var $path; + var $server; + var $port; + var $errno; + var $errstring; + var $debug = 0; + var $username = ""; + var $password = ""; + + function XML_RPC_Client($path, $server, $port = 80, + $proxy = '', $proxy_port = 8080, + $proxy_user = '', $proxy_pass = '') + { + $this->port = $port; + $this->server = $server; + $this->path = $path; + $this->proxy = $proxy; + $this->proxy_port = $proxy_port; + $this->proxy_user = $proxy_user; + $this->proxy_pass = $proxy_pass; + } + + function setDebug($in) + { + if ($in) { + $this->debug = 1; + } else { + $this->debug = 0; + } + } + + function setCredentials($u, $p) + { + $this->username = $u; + $this->password = $p; + } + + function send($msg, $timeout = 0) + { + // where msg is an xmlrpcmsg + $msg->debug = $this->debug; + return $this->sendPayloadHTTP10($msg, $this->server, $this->port, + $timeout, $this->username, + $this->password); + } + + function sendPayloadHTTP10($msg, $server, $port, $timeout=0, + $username = "", $password = "") + { + // If we're using a proxy open a socket to the proxy server instead to the xml-rpc server + if ($this->proxy){ + if ($timeout > 0) { + $fp = fsockopen($this->proxy, $this->proxy_port, $this->errno, $this->errstr, $timeout); + } else { + $fp = fsockopen($this->proxy, $this->proxy_port, $this->errno, $this->errstr); + } + } else { + if ($timeout > 0) { + $fp = fsockopen($server, $port, $this->errno, $this->errstr, $timeout); + } else { + $fp = fsockopen($server, $port, $this->errno, $this->errstr); + } + } + + if (!$fp && $this->proxy) { + $this->raiseError( + "Connection to proxy server " . $this->proxy . ":" . $this->proxy_port . " failed", + XML_RPC_ERROR_CONNECTION_FAILED); + } elseif (!$fp) { + $this->raiseError( + "Connection to RPC server " . $this->server . " failed", + XML_RPC_ERROR_CONNECTION_FAILED); + } + + // Only create the payload if it was not created previously + if (empty($msg->payload)) { + $msg->createPayload(); + } + + // thanks to Grant Rauscher for this + $credentials = ""; + if ($username != "") { + $credentials = "Authorization: Basic " . + base64_encode($username . ":" . $password) . "\r\n"; + } + + + if ($this->proxy) { + $op = "POST http://" . $this->server; + + if ($this->proxy_port) { + $op .= ":" . $this->port; + } + } else { + $op = "POST "; + } + + $op .= $this->path. " HTTP/1.0\r\n" . + "User-Agent: PEAR XML_RPC\r\n" . + "Host: " . $this->server . "\r\n"; + if ($this->proxy && $this->proxy_user != '') { + $op .= 'Proxy-Authorization: Basic ' . + base64_encode($this->proxy_user . ':' . $this->proxy_pass) . + "\r\n"; + } + $op .= $credentials . + "Content-Type: text/xml\r\n" . + "Content-Length: " . strlen($msg->payload) . "\r\n\r\n" . + $msg->payload; + + if (!fputs($fp, $op, strlen($op))) { + $this->errstr = "Write error"; + return 0; + } + $resp = $msg->parseResponseFile($fp); + fclose($fp); + return $resp; + } +} + + +class XML_RPC_Response extends XML_RPC_Base +{ + var $xv; + var $fn; + var $fs; + var $hdrs; + + function XML_RPC_Response($val, $fcode = 0, $fstr = "") + { + if ($fcode != 0) { + $this->fn = $fcode; + $this->fs = htmlspecialchars($fstr); + } else { + $this->xv = $val; + } + } + + function faultCode() + { + if (isset($this->fn)) { + return $this->fn; + } else { + return 0; + } + } + + function faultString() + { + return $this->fs; + } + + function value() + { + return $this->xv; + } + + function serialize() + { + $rs = "\n"; + if ($this->fn) { + $rs .= " + + + + faultCode + " . $this->fn . " + + + faultString + " . $this->fs . " + + + +"; + } else { + $rs .= "\n\n" . $this->xv->serialize() . + "\n"; + } + $rs .= "\n"; + return $rs; + } +} + + +class XML_RPC_Message extends XML_RPC_Base +{ + var $payload; + var $methodname; + var $params = array(); + var $debug = 0; + + function XML_RPC_Message($meth, $pars = 0) + { + $this->methodname = $meth; + if (is_array($pars) && sizeof($pars)>0) { + for($i = 0; $i < sizeof($pars); $i++) { + $this->addParam($pars[$i]); + } + } + } + + function xml_header() + { + return "\n\n"; + } + + function xml_footer() + { + return "\n"; + } + + function createPayload() + { + $this->payload = $this->xml_header(); + $this->payload .= "" . $this->methodname . "\n"; + $this->payload .= "\n"; + for($i = 0; $i < sizeof($this->params); $i++) { + $p = $this->params[$i]; + $this->payload .= "\n" . $p->serialize() . "\n"; + } + $this->payload .= "\n"; + $this->payload .= $this->xml_footer(); + $this->payload = str_replace("\n", "\r\n", $this->payload); + } + + function method($meth = "") + { + if ($meth != "") { + $this->methodname = $meth; + } + return $this->methodname; + } + + function serialize() + { + $this->createPayload(); + return $this->payload; + } + + function addParam($par) + { + $this->params[] = $par; + } + + function getParam($i) + { + return $this->params[$i]; + } + + function getNumParams() + { + return sizeof($this->params); + } + + function parseResponseFile($fp) + { + $ipd = ""; + + while($data = fread($fp, 32768)) { + $ipd .= $data; + } + return $this->parseResponse($ipd); + } + + function parseResponse($data = "") + { + global $XML_RPC_xh,$XML_RPC_err,$XML_RPC_str; + global $XML_RPC_defencoding; + + $parser = xml_parser_create($XML_RPC_defencoding); + + $XML_RPC_xh[$parser] = array(); + + $XML_RPC_xh[$parser]['st'] = ""; + $XML_RPC_xh[$parser]['cm'] = 0; + $XML_RPC_xh[$parser]['isf'] = 0; + $XML_RPC_xh[$parser]['ac'] = ""; + $XML_RPC_xh[$parser]['qt'] = ""; + + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, "XML_RPC_se", "XML_RPC_ee"); + xml_set_character_data_handler($parser, "XML_RPC_cd"); + xml_set_default_handler($parser, "XML_RPC_dh"); + $xmlrpc_value = new XML_RPC_Value; + + $hdrfnd = 0; + if ($this->debug) { + print "
---GOT---\n";
+            print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
+            print "\n---END---\n
"; + } + + // see if we got an HTTP 200 OK, else bomb + // but only do this if we're using the HTTP protocol. + if (ereg("^HTTP",$data) && + !ereg("^HTTP/[0-9\.]+ 200 ", $data)) { + $errstr = substr($data, 0, strpos($data, "\n")-1); + error_log("HTTP error, got response: " . $errstr); + $r = new XML_RPC_Response(0, $XML_RPC_err["http_error"], + $XML_RPC_str["http_error"] . " (" . + $errstr . ")"); + xml_parser_free($parser); + return $r; + } + // gotta get rid of headers here + + + if ((!$hdrfnd) && ($brpos = strpos($data,"\r\n\r\n"))) { + $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos); + $data = substr($data, $brpos + 4); + $hdrfnd = 1; + } + + // be tolerant of junk after methodResponse (e.g. javascript automatically inserted by free hosts) + // thanks to Luca Mariano + $data = substr($data, 0, strpos($data, "") + 17); + + if (!xml_parse($parser, $data, sizeof($data))) { + // thanks to Peter Kocks + if ((xml_get_current_line_number($parser)) == 1) { + $errstr = "XML error at line 1, check URL"; + } else { + $errstr = sprintf("XML error: %s at line %d", + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser)); + } + error_log($errstr); + $r = new XML_RPC_Response(0, $XML_RPC_err["invalid_return"], + $XML_RPC_str["invalid_return"]); + xml_parser_free($parser); + return $r; + } + xml_parser_free($parser); + if ($this->debug) { + print "
---EVALING---[" .
+            strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
+            htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---
"; + } + if (strlen($XML_RPC_xh[$parser]['st']) == 0) { + // then something odd has happened + // and it's time to generate a client side error + // indicating something odd went on + $r = new XML_RPC_Response(0, $XML_RPC_err["invalid_return"], + $XML_RPC_str["invalid_return"]); + } else { + eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;'); + if ($XML_RPC_xh[$parser]['isf']) { + $f = $v->structmem("faultCode"); + $fs = $v->structmem("faultString"); + $r = new XML_RPC_Response($v, $f->scalarval(), + $fs->scalarval()); + } else { + $r = new XML_RPC_Response($v); + } + } + $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]); + return $r; + } + +} + + +class XML_RPC_Value extends XML_RPC_Base +{ + var $me = array(); + var $mytype = 0; + + function XML_RPC_Value($val = -1, $type = "") + { + global $XML_RPC_Types; + $this->me = array(); + $this->mytype = 0; + if ($val != -1 || $type != "") { + if ($type == "") { + $type="string"; + } + if ($XML_RPC_Types[$type] == 1) { + $this->addScalar($val,$type); + } elseif ($XML_RPC_Types[$type] == 2) { + $this->addArray($val); + } elseif ($XML_RPC_Types[$type] == 3) { + $this->addStruct($val); + } + } + } + + function addScalar($val, $type = "string") + { + global $XML_RPC_Types, $XML_RPC_Boolean; + + if ($this->mytype == 1) { + $this->raiseError("Scalar can have only one value", XML_RPC_ERROR_INVALID_TYPE); + return 0; + } + $typeof = $XML_RPC_Types[$type]; + if ($typeof != 1) { + $this->raiseError("Not a scalar type (${typeof})", XML_RPC_ERROR_INVALID_TYPE); + return 0; + } + + if ($type == $XML_RPC_Boolean) { + if (strcasecmp($val,"true") == 0 || + $val == 1 || + ($val == true && + strcasecmp($val,"false"))) { + + $val = 1; + } else { + $val = 0; + } + } + + if ($this->mytype == 2) { + // we're adding to an array here + $ar = $this->me["array"]; + $ar[] = new XML_RPC_Value($val, $type); + $this->me["array"] = $ar; + } else { + // a scalar, so set the value and remember we're scalar + $this->me[$type] = $val; + $this->mytype = $typeof; + } + return 1; + } + + function addArray($vals) + { + global $XML_RPC_Types; + if ($this->mytype != 0) { + $this->raiseError( + "Already initialized as a [" . $this->kindOf() . "]", + XML_RPC_ERROR_ALREADY_INITIALIZED); + return 0; + } + $this->mytype = $XML_RPC_Types["array"]; + $this->me["array"] = $vals; + return 1; + } + + function addStruct($vals) + { + global $XML_RPC_Types; + if ($this->mytype != 0) { + $this->raiseError( + "Already initialized as a [" . $this->kindOf() . "]", + XML_RPC_ERROR_ALREADY_INITIALIZED); + return 0; + } + $this->mytype = $XML_RPC_Types["struct"]; + $this->me["struct"] = $vals; + return 1; + } + + function dump($ar) + { + reset($ar); + while (list( $key, $val ) = each($ar)) { + echo "$key => $val
"; + if ($key == 'array') { + while ( list( $key2, $val2 ) = each( $val ) ) { + echo "-- $key2 => $val2
"; + } + } + } + } + + function kindOf() + { + switch ($this->mytype) { + case 3: + return "struct"; + break; + case 2: + return "array"; + break; + case 1: + return "scalar"; + break; + default: + return "undef"; + } + } + + function serializedata($typ, $val) + { + $rs = ""; + global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean; + switch ($XML_RPC_Types[$typ]) { + case 3: + // struct + $rs .= "\n"; + reset($val); + while(list($key2, $val2) = each($val)) { + $rs .= "${key2}\n"; + $rs .= $this->serializeval($val2); + $rs .= "\n"; + } + $rs .= ""; + break; + case 2: + // array + $rs .= "\n\n"; + for($i = 0; $i < sizeof($val); $i++) { + $rs .= $this->serializeval($val[$i]); + } + $rs .= "\n"; + break; + case 1: + switch ($typ) { + case $XML_RPC_Base64: + $rs .= "<${typ}>" . base64_encode($val) . ""; + break; + case $XML_RPC_Boolean: + $rs .= "<${typ}>" . ($val ? "1" : "0") . ""; + break; + case $XML_RPC_String: + $rs .= "<${typ}>" . htmlspecialchars($val). ""; + break; + default: + $rs .= "<${typ}>${val}"; + } + break; + default: + break; + } + return $rs; + } + + function serialize() + { + return $this->serializeval($this); + } + + function serializeval($o) + { + $rs = ""; + $ar = $o->me; + reset($ar); + list($typ, $val) = each($ar); + $rs .= ""; + $rs .= $this->serializedata($typ, $val); + $rs .= "\n"; + return $rs; + } + + function structmem($m) + { + $nv = $this->me["struct"][$m]; + return $nv; + } + + function structreset() + { + reset($this->me["struct"]); + } + + function structeach() + { + return each($this->me["struct"]); + } + + function getval() { + // UNSTABLE + global $XML_RPC_BOOLEAN, $XML_RPC_Base64; + + reset($this->me); + list($a,$b) = each($this->me); + + // contributed by I Sofer, 2001-03-24 + // add support for nested arrays to scalarval + // i've created a new method here, so as to + // preserve back compatibility + + if (is_array($b)) { + foreach ($b as $id => $cont) { + $b[$id] = $cont->scalarval(); + } + } + + // add support for structures directly encoding php objects + if (is_object($b)) { + $t = get_object_vars($b); + foreach ($t as $id => $cont) { + $t[$id] = $cont->scalarval(); + } + foreach ($t as $id => $cont) { + eval('$b->'.$id.' = $cont;'); + } + } + + // end contrib + return $b; + } + + function scalarval() + { + global $XML_RPC_Boolean, $XML_RPC_Base64; + reset($this->me); + list($a,$b) = each($this->me); + return $b; + } + + function scalartyp() + { + global $XML_RPC_I4, $XML_RPC_Int; + reset($this->me); + list($a,$b) = each($this->me); + if ($a == $XML_RPC_I4) { + $a = $XML_RPC_Int; + } + return $a; + } + + function arraymem($m) + { + $nv = $this->me["array"][$m]; + return $nv; + } + + function arraysize() + { + reset($this->me); + list($a,$b) = each($this->me); + return sizeof($b); + } +} + + +/** + * date helpers + */ +function XML_RPC_iso8601_encode($timet, $utc = 0) { + // return an ISO8601 encoded string + // really, timezones ought to be supported + // but the XML-RPC spec says: + // + // "Don't assume a timezone. It should be specified by the server in its + // documentation what assumptions it makes about timezones." + // + // these routines always assume localtime unless + // $utc is set to 1, in which case UTC is assumed + // and an adjustment for locale is made when encoding + if (!$utc) { + $t = strftime("%Y%m%dT%H:%M:%S", $timet); + } else { + if (function_exists("gmstrftime")) { + // gmstrftime doesn't exist in some versions + // of PHP + $t = gmstrftime("%Y%m%dT%H:%M:%S", $timet); + } else { + $t = strftime("%Y%m%dT%H:%M:%S", $timet - date("Z")); + } + } + + return $t; +} + +function XML_RPC_iso8601_decode($idate, $utc = 0) { + // return a timet in the localtime, or UTC + $t = 0; + if (ereg("([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})", $idate, $regs)) { + + if ($utc) { + $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } else { + $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); + } + } + + return $t; +} + +/** + * Takes a message in PHP XML_RPC object format and translates it into native PHP types. + * + * @author Dan Libby + **/ +function XML_RPC_decode($XML_RPC_val) { + $kind = $XML_RPC_val->kindOf(); + + if ($kind == "scalar") { + return $XML_RPC_val->scalarval(); + + } elseif ($kind == "array") { + $size = $XML_RPC_val->arraysize(); + $arr = array(); + + for($i = 0; $i < $size; $i++) { + $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i)); + } + return $arr; + + } elseif ($kind == "struct") { + $XML_RPC_val->structreset(); + $arr = array(); + + while(list($key,$value) = $XML_RPC_val->structeach()) { + $arr[$key] = XML_RPC_decode($value); + } + return $arr; + } +} + +/** + * Takes native php types and encodes them into XML_RPC PHP object format. + * + * Feature creep -- could support more types via optional type argument. + * + * @author Dan Libby + **/ +function XML_RPC_encode($php_val) { + global $XML_RPC_Boolean; + global $XML_RPC_Int; + global $XML_RPC_Double; + global $XML_RPC_String; + global $XML_RPC_Array; + global $XML_RPC_Struct; + + $type = gettype($php_val); + $XML_RPC_val = new XML_RPC_Value; + + switch ($type) { + case "array": + $keys = array_keys($php_val); + $count = count($php_val); + $firstkey = $keys[0]; + $lastkey = $keys[$count - 1]; + if ($firstkey === 0 && is_int($lastkey) && ($lastkey + 1) == $count) { + $is_continuous = true; + $expected = 0; + foreach ($keys as $actual) { + if ($actual != $expected) { + $is_continuous = false; + break; + } + $expected++; + } + + if ($is_continuous) { + $arr = array(); + foreach ($php_val as $k => $v) { + $arr[$k] = XML_RPC_encode($v); + } + $XML_RPC_val->addArray($arr); + break; + } + } + // fall though if not numerical and continuous + case "object": + $arr = array(); + foreach ($php_val as $k => $v) { + $arr[$k] = XML_RPC_encode($v); + } + $XML_RPC_val->addStruct($arr); + break; + + case "integer": + $XML_RPC_val->addScalar($php_val, $XML_RPC_Int); + break; + + case "double": + $XML_RPC_val->addScalar($php_val, $XML_RPC_Double); + break; + + case "string": + case "NULL": + $XML_RPC_val->addScalar($php_val, $XML_RPC_String); + break; + + // + // Add support for encoding/decoding of booleans, since they are supported in PHP + case "boolean": + $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean); + break; + // + + case "unknown type": + default: + $XML_RPC_val = false; + break; + } + return $XML_RPC_val; +} + +?> diff --git a/livesupport/modules/storageServer/var/xmlrpc/XML/RPC/Server.php b/livesupport/modules/storageServer/var/xmlrpc/XML/RPC/Server.php new file mode 100644 index 000000000..d9bc7451e --- /dev/null +++ b/livesupport/modules/storageServer/var/xmlrpc/XML/RPC/Server.php @@ -0,0 +1,310 @@ + + +// License is granted to use or modify this software ("XML-RPC for PHP") +// for commercial or non-commercial use provided the copyright of the author +// is preserved in any distributed or derivative work. + +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Adapted to PEAR standards by Stig S�her Bakken +// /* $Id: Server.php,v 1.1 2004/12/15 17:25:50 tomas Exp $ */ + +require_once "XML/RPC.php"; + +// listMethods: either a string, or nothing +$GLOBALS['XML_RPC_Server_listMethods_sig'] = + array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String']), + array($GLOBALS['XML_RPC_Array'])); +$GLOBALS['XML_RPC_Server_listMethods_doc'] = + 'This method lists all the methods that the XML-RPC server knows how to dispatch'; + +function XML_RPC_Server_listMethods($server, $m) +{ + global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; + $v = new XML_RPC_Value(); + $dmap = $server->dmap; + $outAr = array(); + for (reset($dmap); list($key, $val) = each($dmap); ) { + $outAr[] = new XML_RPC_Value($key, "string"); + } + $dmap = $XML_RPC_Server_dmap; + for (reset($dmap); list($key, $val) = each($dmap); ) { + $outAr[] = new XML_RPC_Value($key, "string"); + } + $v->addArray($outAr); + return new XML_RPC_Response($v); +} + +$GLOBALS['XML_RPC_Server_methodSignature_sig'] = + array(array($GLOBALS['XML_RPC_Array'], $GLOBALS['XML_RPC_String'])); +$GLOBALS['XML_RPC_Server_methodSignature_doc'] = + 'Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)'; + +function XML_RPC_Server_methodSignature($server, $m) +{ + global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; + + $methName = $m->getParam(0); + $methName = $methName->scalarval(); + if (ereg("^system\.", $methName)) { + $dmap = $XML_RPC_Server_dmap; + $sysCall = 1; + } else { + $dmap = $server->dmap; + $sysCall = 0; + } + // print "\n"; + if (isset($dmap[$methName])) { + if ($dmap[$methName]["signature"]) { + $sigs = array(); + $thesigs = $dmap[$methName]["signature"]; + for ($i = 0; $i < sizeof($thesigs); $i++) { + $cursig = array(); + $inSig = $thesigs[$i]; + for ($j = 0; $j < sizeof($inSig); $j++) { + $cursig[] = new XML_RPC_Value($inSig[$j], "string"); + } + $sigs[] = new XML_RPC_Value($cursig, "array"); + } + $r = new XML_RPC_Response(new XML_RPC_Value($sigs, "array")); + } else { + $r = new XML_RPC_Response(new XML_RPC_Value("undef", "string")); + } + } else { + $r = new XML_RPC_Response(0, $XML_RPC_err["introspect_unknown"], + $XML_RPC_str["introspect_unknown"]); + } + return $r; +} + +$GLOBALS['XML_RPC_Server_methodHelp_sig'] = + array(array($GLOBALS['XML_RPC_String'], $GLOBALS['XML_RPC_String'])); +$GLOBALS['XML_RPC_Server_methodHelp_doc'] = + 'Returns help text if defined for the method passed, otherwise returns an empty string'; + +function XML_RPC_Server_methodHelp($server, $m) +{ + global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap; + + $methName = $m->getParam(0); + $methName = $methName->scalarval(); + if (ereg("^system\.", $methName)) { + $dmap = $XML_RPC_Server_dmap; + $sysCall = 1; + } else { + $dmap = $server->dmap; + $sysCall = 0; + } + // print "\n"; + if (isset($dmap[$methName])) { + if ($dmap[$methName]["docstring"]) { + $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]["docstring"]), "string"); + } else { + $r = new XML_RPC_Response(new XML_RPC_Value("", "string")); + } + } else { + $r = new XML_RPC_Response(0, $XML_RPC_err["introspect_unknown"], + $XML_RPC_str["introspect_unknown"]); + } + return $r; +} + +$GLOBALS['XML_RPC_Server_dmap'] = array( + "system.listMethods" => + array("function" => "XML_RPC_Server_listMethods", + "signature" => $GLOBALS['XML_RPC_Server_listMethods_sig'], + "docstring" => $GLOBALS['XML_RPC_Server_listMethods_doc']), + + "system.methodHelp" => + array("function" => "XML_RPC_Server_methodHelp", + "signature" => $GLOBALS['XML_RPC_Server_methodHelp_sig'], + "docstring" => $GLOBALS['XML_RPC_Server_methodHelp_doc']), + + "system.methodSignature" => + array("function" => "XML_RPC_Server_methodSignature", + "signature" => $GLOBALS['XML_RPC_Server_methodSignature_sig'], + "docstring" => $GLOBALS['XML_RPC_Server_methodSignature_doc']) +); + +$GLOBALS['XML_RPC_Server_debuginfo'] = ""; + +function XML_RPC_Server_debugmsg($m) +{ + global $XML_RPC_Server_debuginfo; + $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n"; +} + +class XML_RPC_Server +{ + var $dmap = array(); + + function XML_RPC_Server($dispMap, $serviceNow = 1) + { + global $HTTP_RAW_POST_DATA; + // dispMap is a despatch array of methods + // mapped to function names and signatures + // if a method + // doesn't appear in the map then an unknown + // method error is generated + $this->dmap = $dispMap; + if ($serviceNow) { + $this->service(); + } + } + + function serializeDebug() + { + global $XML_RPC_Server_debuginfo; + if ($XML_RPC_Server_debuginfo != "") + return "\n"; + else + return ""; + } + + function service() + { + $r = $this->parseRequest(); + $payload = "\n" . + $this->serializeDebug() . + $r->serialize(); + header('Content-Length: ' . strlen($payload)); + header('Content-Type: text/xml'); + print $payload; + } + + function verifySignature($in, $sig) + { + for ($i = 0; $i < sizeof($sig); $i++) { + // check each possible signature in turn + $cursig = $sig[$i]; + if (sizeof($cursig) == $in->getNumParams() + 1) { + $itsOK = 1; + for ($n = 0; $n < $in->getNumParams(); $n++) { + $p = $in->getParam($n); + // print "\n"; + if ($p->kindOf() == "scalar") { + $pt = $p->scalartyp(); + } else { + $pt = $p->kindOf(); + } + // $n+1 as first type of sig is return type + if ($pt != $cursig[$n+1]) { + $itsOK = 0; + $pno = $n+1; + $wanted = $cursig[$n+1]; + $got = $pt; + break; + } + } + if ($itsOK) + return array(1); + } + } + return array(0, "Wanted ${wanted}, got ${got} at param ${pno})"); + } + + function parseRequest($data = "") + { + global $XML_RPC_xh,$HTTP_RAW_POST_DATA; + global $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml, + $XML_RPC_defencoding, $XML_RPC_Server_dmap; + + if ($data == "") { + $data = $HTTP_RAW_POST_DATA; + } + $parser = xml_parser_create($XML_RPC_defencoding); + + $XML_RPC_xh[$parser] = array(); + $XML_RPC_xh[$parser]['st'] = ""; + $XML_RPC_xh[$parser]['cm'] = 0; + $XML_RPC_xh[$parser]['isf'] = 0; + $XML_RPC_xh[$parser]['params'] = array(); + $XML_RPC_xh[$parser]['method'] = ""; + + $plist = ''; + + // decompose incoming XML into request structure + + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); + xml_set_element_handler($parser, "XML_RPC_se", "XML_RPC_ee"); + xml_set_character_data_handler($parser, "XML_RPC_cd"); + xml_set_default_handler($parser, "XML_RPC_dh"); + if (!xml_parse($parser, $data, 1)) { + // return XML error as a faultCode + $r = new XML_RPC_Response(0, + $XML_RPC_errxml+xml_get_error_code($parser), + sprintf("XML error: %s at line %d", + xml_error_string(xml_get_error_code($parser)), + xml_get_current_line_number($parser))); + xml_parser_free($parser); + } else { + xml_parser_free($parser); + $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']); + // now add parameters in + for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) { + // print "\n"; + $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n"; + eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ");"); + } + XML_RPC_Server_debugmsg($plist); + // now to deal with the method + $methName = $XML_RPC_xh[$parser]['method']; + if (ereg("^system\.", $methName)) { + $dmap = $XML_RPC_Server_dmap; + $sysCall = 1; + } else { + $dmap = $this->dmap; + $sysCall = 0; + } + if (isset($dmap[$methName]['function'])) { + // dispatch if exists + if (isset($dmap[$methName]['signature'])) { + $sr = $this->verifySignature($m, + $dmap[$methName]['signature'] ); + } + if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) { + // if no signature or correct signature + if ($sysCall) { + eval('$r=' . $dmap[$methName]['function'] . '($this, $m);'); + } else { + eval('$r=' . $dmap[$methName]['function'] . '($m);'); + } + } else { + $r = new XML_RPC_Response(0, $XML_RPC_err["incorrect_params"], + $XML_RPC_str["incorrect_params"] . + ": " . $sr[1]); + } + } else { + // else prepare error response + $r = new XML_RPC_Response(0, $XML_RPC_err["unknown_method"], + $XML_RPC_str["unknown_method"]); + } + } + return $r; + } + + function echoInput() { + global $HTTP_RAW_POST_DATA; + + // a debugging routine: just echos back the input + // packet as a string value + + $r = new XML_RPC_Response; + $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, "string"); + print $r->serialize(); + } +} + +?> diff --git a/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php b/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php index 808667318..dad35e7b7 100644 --- a/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php +++ b/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php @@ -23,7 +23,7 @@ Author : $Author: tomas $ - Version : $Revision: 1.7 $ + Version : $Revision: 1.8 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php,v $ ------------------------------------------------------------------------------*/ @@ -48,9 +48,9 @@ ini_set("error_append_string", "
"); header("Content-type: text/xml"); +require_once 'DB.php'; require_once "XML/RPC/Server.php"; require_once '../conf.php'; -require_once 'DB.php'; require_once '../LocStor.php'; function errHndl($errno, $errmsg, $filename, $linenum, $vars){