Logo Search packages:      
Sourcecode: b2evolution version File versions  Download package

_functions_xmlrpc.php

<?php
/**
 * @package evocore
 * @subpackage xmlrpc {@link http://xmlrpc.usefulinc.com/doc/}
 * @copyright Edd Dumbill <edd@usefulinc.com> (C) 1999-2001
 */
// by Edd Dumbill (C) 1999-2002
// <edd@usefulinc.com>
// $Id: _functions_xmlrpc.php,v 1.9.2.6 2005/08/31 19:32:31 fplanque Exp $

// additional fixes for case of missing xml extension file by Michel Valdrighi <m@tidakada.com>

// Copyright (c) 1999,2000,2002 Edd Dumbill.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above
//      copyright notice, this list of conditions and the following
//      disclaimer in the documentation and/or other materials provided
//      with the distribution.
//
//    * Neither the name of the "XML-RPC for PHP" nor the names of its
//      contributors may be used to endorse or promote products derived
//      from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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
// REGENTS OR CONTRIBUTORS 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.

if( !defined('DB_USER') ) die( 'Please, do not access this page directly.' );

      # b2 fix. some servers have stupid warnings
      # error_reporting(0);

      /**
       * logIO(-)
       */
      if (!function_exists('logIO'))
      {
            function logIO($m="",$n="")
            {
                  return(true);
            }
      }

      // Original fix for missing extension file by "Michel Valdrighi" <m@tidakada.com>
      if(function_exists('xml_parser_create'))
      {
            define("CANUSEXMLRPC", 1);
      }
      elseif( !(bool)ini_get('enable_dl') || (bool)ini_get('safe_mode'))
      { // We'll not be able to do dynamic loading (fix by Sakichan)
            /**
             * @ignore
             */
            define("CANUSEXMLRPC", 0);
      }
      elseif($WINDIR)
      {     // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
            if (@dl("php3_xml.dll"))
            {
                  /**
                   * @ignore
                   */
                  define("CANUSEXMLRPC", 1);
            }
            else
            {
                  /**
                   * @ignore
                   */
                  define("CANUSEXMLRPC", 0);
            }
      }
      else
      {
            if (@dl("xml.so"))
            {
                  /**
                   * @ignore
                   */
                  define("CANUSEXMLRPC", 1);
            }
            else
            {
                  /**
                   * @ignore
                   */
                  define("CANUSEXMLRPC", 0);
            }
      }

      if( ! CANUSEXMLRPC == 1 )
      {
            return;
      }


      // G. Giunta 2005/01/29: declare global these variables,
      // so that xmlrpc.inc will work even if included from within a function
      // NB: it will give warnings in PHP3, so we comment it out
      // Milosch: Next round, maybe we should explicitly request these via $GLOBALS where used.
      if (phpversion() >= '4')
      {
            global $xmlrpcI4;
            global $xmlrpcInt;
            global $xmlrpcDouble;
            global $xmlrpcBoolean;
            global $xmlrpcString;
            global $xmlrpcDateTime;
            global $xmlrpcBase64;
            global $xmlrpcArray;
            global $xmlrpcStruct;

            global $xmlrpcTypes;
            global $xmlEntities;
            global $xmlrpcerr;
            global $xmlrpcstr;
            global $xmlrpc_defencoding;
            global $xmlrpc_internalencoding;
            global $xmlrpcName;
            global $xmlrpcVersion;
            global $xmlrpcerruser;
            global $xmlrpcerrxml;
            global $xmlrpc_backslash;
            global $_xh;
      }
      $xmlrpcI4='i4';
      $xmlrpcInt='int';
      $xmlrpcBoolean='boolean';
      $xmlrpcDouble='double';
      $xmlrpcString='string';
      $xmlrpcDateTime='dateTime.iso8601';
      $xmlrpcBase64='base64';
      $xmlrpcArray='array';
      $xmlrpcStruct='struct';

      $xmlrpcTypes=array(
            $xmlrpcI4       => 1,
            $xmlrpcInt      => 1,
            $xmlrpcBoolean  => 1,
            $xmlrpcString   => 1,
            $xmlrpcDouble   => 1,
            $xmlrpcDateTime => 1,
            $xmlrpcBase64   => 1,
            $xmlrpcArray    => 2,
            $xmlrpcStruct   => 3
      );

      $xmlrpc_valid_parents = array(
            'BOOLEAN' => array('VALUE'),
            'I4' => array('VALUE'),
            'INT' => array('VALUE'),
            'STRING' => array('VALUE'),
            'DOUBLE' => array('VALUE'),
            'DATETIME.ISO8601' => array('VALUE'),
            'BASE64' => array('VALUE'),
            'ARRAY' => array('VALUE'),
            'STRUCT' => array('VALUE'),
            'PARAM' => array('PARAMS'),
            'METHODNAME' => array('METHODCALL'),
            'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
            'MEMBER' => array('STRUCT'),
            'NAME' => array('MEMBER'),
            'DATA' => array('ARRAY'),
            'FAULT' => array('METHODRESPONSE'),
            'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT'),
      );

      $xmlEntities=array(
            'amp'  => '&',
            'quot' => '"',
            'lt'   => '<',
            'gt'   => '>',
            'apos' => "'"
      );
      // These are left untranslated because they are sent back to the remote system
      $xmlrpcerr['unknown_method']=1;
      $xmlrpcstr['unknown_method']='Unknown method';
      $xmlrpcerr['invalid_return']=2;
      $xmlrpcstr['invalid_return']='Invalid return payload: enable debugging to examine incoming payload';
      $xmlrpcerr['incorrect_params']=3;
      $xmlrpcstr['incorrect_params']='Incorrect parameters passed to method';
      $xmlrpcerr['introspect_unknown']=4;
      $xmlrpcstr['introspect_unknown']="Can't introspect: method unknown";
      $xmlrpcerr['http_error']=5;
      $xmlrpcstr['http_error']="Didn't receive 200 OK from remote server.";
      $xmlrpcerr['no_data']=6;
      $xmlrpcstr['no_data']='No data received from server.';
      $xmlrpcerr['no_ssl']=7;
      $xmlrpcstr['no_ssl']='No SSL support compiled in.';
      $xmlrpcerr['curl_fail']=8;
      $xmlrpcstr['curl_fail']='CURL error';
      $xmlrpcerr['invalid_request']=15;
      $xmlrpcstr['invalid_request']='Invalid request payload';

      $xmlrpcerr['multicall_notstruct'] = 9;
      $xmlrpcstr['multicall_notstruct'] = 'system.multicall expected struct';
      $xmlrpcerr['multicall_nomethod']  = 10;
      $xmlrpcstr['multicall_nomethod']  = 'missing methodName';
      $xmlrpcerr['multicall_notstring'] = 11;
      $xmlrpcstr['multicall_notstring'] = 'methodName is not a string';
      $xmlrpcerr['multicall_recursion'] = 12;
      $xmlrpcstr['multicall_recursion'] = 'recursive system.multicall forbidden';
      $xmlrpcerr['multicall_noparams']  = 13;
      $xmlrpcstr['multicall_noparams']  = 'missing params';
      $xmlrpcerr['multicall_notarray']  = 14;
      $xmlrpcstr['multicall_notarray']  = 'params is not an array';

      // The charset encoding expected by the server for received messages and
      // by the client for received responses
      $xmlrpc_defencoding='UTF-8';
      // The encoding used by PHP.
      // String values received will be converted to this.
      $xmlrpc_internalencoding='ISO-8859-1';

      $xmlrpcName='XML-RPC for PHP';
      $xmlrpcVersion='1.2';

      // let user errors start at 800
      $xmlrpcerruser=800;
      // let XML parse errors start at 100
      $xmlrpcerrxml=100;

      // formulate backslashes for escaping regexp
      $xmlrpc_backslash=chr(92).chr(92);

      // used to store state during parsing
      // quick explanation of components:
      //   ac - used to accumulate values
      //   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
      //   stack - array with genealogy of xml elements names:
      //           used to validate nesting of xmlrpc elements

      $_xh=array();

      /**
      * To help correct communication of non-ascii chars inside strings, regardless
      * of the charset used when sending requests, parsing them, sending responses
      * and parsing responses, convert all non-ascii chars present in the message
      * into their equivalent 'charset entity'. Charset entities enumerated this way
      * are independent of the charset encoding used to transmit them, and all XML
      * parsers are bound to understand them.
      */
      function xmlrpc_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]+;",
                        xmlrpc_lookup_entity($regs[1]),
                        $top[$i]);
                  }
                  else
                  {
                        if ($i==0)
                        {
                              $op=$top[$i];
                        }
                        else
                        {
                              $op.='&' . $top[$i];
                        }
                  }
                  $i++;
            }
            return $op;
      }

      function xmlrpc_lookup_entity($ent)
      {
            global $xmlEntities;

            if (isset($xmlEntities[strtolower($ent)]))
            {
                  return $xmlEntities[strtolower($ent)];
            }
            if (ereg("^#([0-9]+)$", $ent, $regs))
            {
                  return chr($regs[1]);
            }
            return '?';
      }

      /**
       * These entities originate from HTML specs (1.1, proposed 2.0, etc),
       * and are taken directly from php-4.3.1/ext/mbstring/html_entities.c.
       * Until php provides functionality to translate these entities in its
       * core library, use this function.
       */
      function xmlrpc_html_entity_xlate($data = '')
      {
            $entities = array(
                  "&nbsp;" => "&#160;",
                  "&iexcl;" => "&#161;",
                  "&cent;" => "&#162;",
                  "&pound;" => "&#163;",
                  "&curren;" => "&#164;",
                  "&yen;" => "&#165;",
                  "&brvbar;" => "&#166;",
                  "&sect;" => "&#167;",
                  "&uml;" => "&#168;",
                  "&copy;" => "&#169;",
                  "&ordf;" => "&#170;",
                  "&laquo;" => "&#171;",
                  "&not;" => "&#172;",
                  "&shy;" => "&#173;",
                  "&reg;" => "&#174;",
                  "&macr;" => "&#175;",
                  "&deg;" => "&#176;",
                  "&plusmn;" => "&#177;",
                  "&sup2;" => "&#178;",
                  "&sup3;" => "&#179;",
                  "&acute;" => "&#180;",
                  "&micro;" => "&#181;",
                  "&para;" => "&#182;",
                  "&middot;" => "&#183;",
                  "&cedil;" => "&#184;",
                  "&sup1;" => "&#185;",
                  "&ordm;" => "&#186;",
                  "&raquo;" => "&#187;",
                  "&frac14;" => "&#188;",
                  "&frac12;" => "&#189;",
                  "&frac34;" => "&#190;",
                  "&iquest;" => "&#191;",
                  "&Agrave;" => "&#192;",
                  "&Aacute;" => "&#193;",
                  "&Acirc;" => "&#194;",
                  "&Atilde;" => "&#195;",
                  "&Auml;" => "&#196;",
                  "&Aring;" => "&#197;",
                  "&AElig;" => "&#198;",
                  "&Ccedil;" => "&#199;",
                  "&Egrave;" => "&#200;",
                  "&Eacute;" => "&#201;",
                  "&Ecirc;" => "&#202;",
                  "&Euml;" => "&#203;",
                  "&Igrave;" => "&#204;",
                  "&Iacute;" => "&#205;",
                  "&Icirc;" => "&#206;",
                  "&Iuml;" => "&#207;",
                  "&ETH;" => "&#208;",
                  "&Ntilde;" => "&#209;",
                  "&Ograve;" => "&#210;",
                  "&Oacute;" => "&#211;",
                  "&Ocirc;" => "&#212;",
                  "&Otilde;" => "&#213;",
                  "&Ouml;" => "&#214;",
                  "&times;" => "&#215;",
                  "&Oslash;" => "&#216;",
                  "&Ugrave;" => "&#217;",
                  "&Uacute;" => "&#218;",
                  "&Ucirc;" => "&#219;",
                  "&Uuml;" => "&#220;",
                  "&Yacute;" => "&#221;",
                  "&THORN;" => "&#222;",
                  "&szlig;" => "&#223;",
                  "&agrave;" => "&#224;",
                  "&aacute;" => "&#225;",
                  "&acirc;" => "&#226;",
                  "&atilde;" => "&#227;",
                  "&auml;" => "&#228;",
                  "&aring;" => "&#229;",
                  "&aelig;" => "&#230;",
                  "&ccedil;" => "&#231;",
                  "&egrave;" => "&#232;",
                  "&eacute;" => "&#233;",
                  "&ecirc;" => "&#234;",
                  "&euml;" => "&#235;",
                  "&igrave;" => "&#236;",
                  "&iacute;" => "&#237;",
                  "&icirc;" => "&#238;",
                  "&iuml;" => "&#239;",
                  "&eth;" => "&#240;",
                  "&ntilde;" => "&#241;",
                  "&ograve;" => "&#242;",
                  "&oacute;" => "&#243;",
                  "&ocirc;" => "&#244;",
                  "&otilde;" => "&#245;",
                  "&ouml;" => "&#246;",
                  "&divide;" => "&#247;",
                  "&oslash;" => "&#248;",
                  "&ugrave;" => "&#249;",
                  "&uacute;" => "&#250;",
                  "&ucirc;" => "&#251;",
                  "&uuml;" => "&#252;",
                  "&yacute;" => "&#253;",
                  "&thorn;" => "&#254;",
                  "&yuml;" => "&#255;",
                  "&OElig;" => "&#338;",
                  "&oelig;" => "&#339;",
                  "&Scaron;" => "&#352;",
                  "&scaron;" => "&#353;",
                  "&Yuml;" => "&#376;",
                  "&fnof;" => "&#402;",
                  "&circ;" => "&#710;",
                  "&tilde;" => "&#732;",
                  "&Alpha;" => "&#913;",
                  "&Beta;" => "&#914;",
                  "&Gamma;" => "&#915;",
                  "&Delta;" => "&#916;",
                  "&Epsilon;" => "&#917;",
                  "&Zeta;" => "&#918;",
                  "&Eta;" => "&#919;",
                  "&Theta;" => "&#920;",
                  "&Iota;" => "&#921;",
                  "&Kappa;" => "&#922;",
                  "&Lambda;" => "&#923;",
                  "&Mu;" => "&#924;",
                  "&Nu;" => "&#925;",
                  "&Xi;" => "&#926;",
                  "&Omicron;" => "&#927;",
                  "&Pi;" => "&#928;",
                  "&Rho;" => "&#929;",
                  "&Sigma;" => "&#931;",
                  "&Tau;" => "&#932;",
                  "&Upsilon;" => "&#933;",
                  "&Phi;" => "&#934;",
                  "&Chi;" => "&#935;",
                  "&Psi;" => "&#936;",
                  "&Omega;" => "&#937;",
                  "&beta;" => "&#946;",
                  "&gamma;" => "&#947;",
                  "&delta;" => "&#948;",
                  "&epsilon;" => "&#949;",
                  "&zeta;" => "&#950;",
                  "&eta;" => "&#951;",
                  "&theta;" => "&#952;",
                  "&iota;" => "&#953;",
                  "&kappa;" => "&#954;",
                  "&lambda;" => "&#955;",
                  "&mu;" => "&#956;",
                  "&nu;" => "&#957;",
                  "&xi;" => "&#958;",
                  "&omicron;" => "&#959;",
                  "&pi;" => "&#960;",
                  "&rho;" => "&#961;",
                  "&sigmaf;" => "&#962;",
                  "&sigma;" => "&#963;",
                  "&tau;" => "&#964;",
                  "&upsilon;" => "&#965;",
                  "&phi;" => "&#966;",
                  "&chi;" => "&#967;",
                  "&psi;" => "&#968;",
                  "&omega;" => "&#969;",
                  "&thetasym;" => "&#977;",
                  "&upsih;" => "&#978;",
                  "&piv;" => "&#982;",
                  "&ensp;" => "&#8194;",
                  "&emsp;" => "&#8195;",
                  "&thinsp;" => "&#8201;",
                  "&zwnj;" => "&#8204;",
                  "&zwj;" => "&#8205;",
                  "&lrm;" => "&#8206;",
                  "&rlm;" => "&#8207;",
                  "&ndash;" => "&#8211;",
                  "&mdash;" => "&#8212;",
                  "&lsquo;" => "&#8216;",
                  "&rsquo;" => "&#8217;",
                  "&sbquo;" => "&#8218;",
                  "&ldquo;" => "&#8220;",
                  "&rdquo;" => "&#8221;",
                  "&bdquo;" => "&#8222;",
                  "&dagger;" => "&#8224;",
                  "&Dagger;" => "&#8225;",
                  "&bull;" => "&#8226;",
                  "&hellip;" => "&#8230;",
                  "&permil;" => "&#8240;",
                  "&prime;" => "&#8242;",
                  "&Prime;" => "&#8243;",
                  "&lsaquo;" => "&#8249;",
                  "&rsaquo;" => "&#8250;",
                  "&oline;" => "&#8254;",
                  "&frasl;" => "&#8260;",
                  "&euro;" => "&#8364;",
                  "&weierp;" => "&#8472;",
                  "&image;" => "&#8465;",
                  "&real;" => "&#8476;",
                  "&trade;" => "&#8482;",
                  "&alefsym;" => "&#8501;",
                  "&larr;" => "&#8592;",
                  "&uarr;" => "&#8593;",
                  "&rarr;" => "&#8594;",
                  "&darr;" => "&#8595;",
                  "&harr;" => "&#8596;",
                  "&crarr;" => "&#8629;",
                  "&lArr;" => "&#8656;",
                  "&uArr;" => "&#8657;",
                  "&rArr;" => "&#8658;",
                  "&dArr;" => "&#8659;",
                  "&hArr;" => "&#8660;",
                  "&forall;" => "&#8704;",
                  "&part;" => "&#8706;",
                  "&exist;" => "&#8707;",
                  "&empty;" => "&#8709;",
                  "&nabla;" => "&#8711;",
                  "&isin;" => "&#8712;",
                  "&notin;" => "&#8713;",
                  "&ni;" => "&#8715;",
                  "&prod;" => "&#8719;",
                  "&sum;" => "&#8721;",
                  "&minus;" => "&#8722;",
                  "&lowast;" => "&#8727;",
                  "&radic;" => "&#8730;",
                  "&prop;" => "&#8733;",
                  "&infin;" => "&#8734;",
                  "&ang;" => "&#8736;",
                  "&and;" => "&#8743;",
                  "&or;" => "&#8744;",
                  "&cap;" => "&#8745;",
                  "&cup;" => "&#8746;",
                  "&int;" => "&#8747;",
                  "&there4;" => "&#8756;",
                  "&sim;" => "&#8764;",
                  "&cong;" => "&#8773;",
                  "&asymp;" => "&#8776;",
                  "&ne;" => "&#8800;",
                  "&equiv;" => "&#8801;",
                  "&le;" => "&#8804;",
                  "&ge;" => "&#8805;",
                  "&sub;" => "&#8834;",
                  "&sup;" => "&#8835;",
                  "&nsub;" => "&#8836;",
                  "&sube;" => "&#8838;",
                  "&supe;" => "&#8839;",
                  "&oplus;" => "&#8853;",
                  "&otimes;" => "&#8855;",
                  "&perp;" => "&#8869;",
                  "&sdot;" => "&#8901;",
                  "&lceil;" => "&#8968;",
                  "&rceil;" => "&#8969;",
                  "&lfloor;" => "&#8970;",
                  "&rfloor;" => "&#8971;",
                  "&lang;" => "&#9001;",
                  "&rang;" => "&#9002;",
                  "&loz;" => "&#9674;",
                  "&spades;" => "&#9824;",
                  "&clubs;" => "&#9827;",
                  "&hearts;" => "&#9829;",
                  "&diams;" => "&#9830;");
            return strtr($data, $entities);
      }

      function xmlrpc_encode_entitites($data)
      {
            $length = strlen($data);
            $escapeddata = "";
            for($position = 0; $position < $length; $position++)
            {
                  $character = substr($data, $position, 1);
                  $code = Ord($character);
                  switch($code) {
                        case 34:
                        $character = "&quot;";
                        break;
                        case 38:
                        $character = "&amp;";
                        break;
                        case 39:
                        $character = "&apos;";
                        break;
                        case 60:
                        $character = "&lt;";
                        break;
                        case 62:
                        $character = "&gt;";
                        break;
                        default:
                        if ($code < 32 || $code > 159)
                              $character = ("&#".strval($code).";");
                        break;
                  }
                  $escapeddata .= $character;
            }
            return $escapeddata;
      }

      function xmlrpc_se($parser, $name, $attrs)
      {
            global $_xh, $xmlrpcDateTime, $xmlrpcString, $xmlrpc_valid_parents;

            // if invalid xmlrpc already detected, skip all processing
            if ($_xh[$parser]['isf'] < 2)
            {

            // check for correct element nesting
            // top level element can only be of 2 types
            if (count($_xh[$parser]['stack']) == 0)
            {
                  if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
                  {
                        $_xh[$parser]['isf'] = 2;
                        $_xh[$parser]['isf_reason'] = 'missing top level xmlrpc element';
                        return;
                  }
            }
            else
            {
                  // not top level element: see if parent is OK
                  if (!in_array($_xh[$parser]['stack'][0], $xmlrpc_valid_parents[$name]))
                  {
                        $_xh[$parser]['isf'] = 2;
                        $_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$_xh[$parser]['stack'][0]}";
                        return;
                  }
            }

            switch($name)
            {
                  case 'STRUCT':
                  case 'ARRAY':
                        //$_xh[$parser]['st'].='array(';
                        //$_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
                        //$_xh[$parser]['qt']=0;

                        // create an empty array to hold child values, and push it onto appropriate stack
                        $cur_val = array();
                        $cur_val['values'] = array();
                        $cur_val['type'] = $name;
                        array_unshift($_xh[$parser]['valuestack'], $cur_val);
                        break;
                  case 'METHODNAME':
                  case 'NAME':
                        //$_xh[$parser]['st'].='"';
                        $_xh[$parser]['ac']='';
                        break;
                  case 'FAULT':
                        $_xh[$parser]['isf']=1;
                        break;
                  case 'PARAM':
                        //$_xh[$parser]['st']='';
                        // clear value, so we can check later if no value will passed for this param/member
                        $_xh[$parser]['value']=null;
                break;
                  case 'VALUE':
                        //$_xh[$parser]['st'].='new xmlrpcval(';
                        // look for a value: if this is still true by the
                        // time we reach the end tag for value then the type is string
                        // by implication
                        $_xh[$parser]['vt']='value';
                        $_xh[$parser]['ac']='';
                        //$_xh[$parser]['qt']=0;
                        $_xh[$parser]['lv']=1;
                        break;
                  case 'I4':
                  case 'INT':
                  case 'STRING':
                  case 'BOOLEAN':
                  case 'DOUBLE':
                  case 'DATETIME.ISO8601':
                  case 'BASE64':
                        if ($_xh[$parser]['vt']!='value')
                        {
                              //two data elements inside a value: an error occurred!
                              $_xh[$parser]['isf'] = 2;
                              $_xh[$parser]['isf_reason'] = "$name element following a {$_xh[$parser]['vt']} element inside a single value";
                              return;
                        }

                        // reset the accumulator
                        $_xh[$parser]['ac']='';

                        /*if ($name=='DATETIME.ISO8601' || $name=='STRING')
                        {
                              $_xh[$parser]['qt']=1;
                              if ($name=='DATETIME.ISO8601')
                              {
                                    $_xh[$parser]['vt']=$xmlrpcDateTime;
                              }
                        }
                        elseif ($name=='BASE64')
                        {
                              $_xh[$parser]['qt']=2;
                        }
                        else
                        {
                              // No quoting is required here -- but
                              // at the end of the element we must check
                              // for data format errors.
                              $_xh[$parser]['qt']=0;
                        }*/
                        break;
                  case 'MEMBER':
                        //$_xh[$parser]['ac']='';
                        // avoid warnings later on if no NAME is found before VALUE inside
                        // a struct member predefining member name as NULL
                        $_xh[$parser]['valuestack'][0]['name'] = '';
                        // clear value, so we can check later if no value will passed for this param/member
                        $_xh[$parser]['value']=null;
                        break;
                  case 'DATA':
                  case 'METHODCALL':
                  case 'METHODRESPONSE':
                  case 'PARAMS':
                        // valid elements that add little to processing
                        break;
                  default:
                        /// INVALID ELEMENT: RAISE ISF so that it is later recognized!!!
                        $_xh[$parser]['isf'] = 2;
                        $_xh[$parser]['isf_reason'] = "found not-xmlrpc xml element $name";
                        break;
            }

            // Save current element name to stack, to validate nesting
            array_unshift($_xh[$parser]['stack'], $name);

            if ($name!='VALUE')
            {
                  $_xh[$parser]['lv']=0;
            }
            }
      }

      function xmlrpc_ee($parser, $name)
      {
            global $_xh,$xmlrpcTypes,$xmlrpcString,$xmlrpcDateTime;

            if ($_xh[$parser]['isf'] < 2)
            {

            // push this element name from stack
            // NB: if XML validates, correct opening/closing is guaranteed and
            // we do not have to check for $name == $curr_elem.
            // we also checked for proper nesting at start of elements...
            $curr_elem = array_shift($_xh[$parser]['stack']);

            switch($name)
            {
                  case 'STRUCT':
                  case 'ARRAY':
                        //if ($_xh[$parser]['cm'] && substr($_xh[$parser]['st'], -1) ==',')
                        //{
                        //    $_xh[$parser]['st']=substr($_xh[$parser]['st'],0,-1);
                        //}
                        //$_xh[$parser]['st'].=')';

                        // fetch out of stack array of values, and promote it to current value
                        $cur_val = array_shift($_xh[$parser]['valuestack']);
                        $_xh[$parser]['value'] = $cur_val['values'];

                        $_xh[$parser]['vt']=strtolower($name);
                        //$_xh[$parser]['cm']--;
                        break;
                  case 'NAME':
                        //$_xh[$parser]['st'].= $_xh[$parser]['ac'] . '" => ';
                        $_xh[$parser]['valuestack'][0]['name'] = $_xh[$parser]['ac'];
                        break;
                  case 'BOOLEAN':
                  case 'I4':
                  case 'INT':
                  case 'STRING':
                  case 'DOUBLE':
                  case 'DATETIME.ISO8601':
                  case 'BASE64':
                        $_xh[$parser]['vt']=strtolower($name);
                        //if ($_xh[$parser]['qt']==1)
                        if ($name=='STRING')
                        {
                              // we use double quotes rather than single so backslashification works OK
                              //$_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';
                              $_xh[$parser]['value']=$_xh[$parser]['ac'];
                        }
                        elseif ($name=='DATETIME.ISO8601')
                        {
                              $_xh[$parser]['vt']=$xmlrpcDateTime;
                              $_xh[$parser]['value']=$_xh[$parser]['ac'];
                        }
                        elseif ($name=='BASE64')
                        {
                              //$_xh[$parser]['st'].='base64_decode("'. $_xh[$parser]['ac'] . '")';

                              ///@todo check for failure of base64 decoding / catch warnings
                              $_xh[$parser]['value']=base64_decode($_xh[$parser]['ac']);
                        }
                        elseif ($name=='BOOLEAN')
                        {
                              // special case here: we translate boolean 1 or 0 into PHP
                              // constants true or false
                              // NB: this simple checks helps a lot sanitizing input, ie no
                              // security problems around here
                              if ($_xh[$parser]['ac']=='1')
                              {
                                    //$_xh[$parser]['ac']='true';
                                    $_xh[$parser]['value']=true;
                              }
                              else
                              {
                                    //$_xh[$parser]['ac']='false';
                                    // log if receiveing something strange, even though we set the value to false anyway
                                    if ($_xh[$parser]['ac']!='0')
                                          error_log('XML-RPC: invalid value received in BOOLEAN: '.$_xh[$parser]['ac']);
                                    $_xh[$parser]['value']=false;
                              }
                              //$_xh[$parser]['st'].=$_xh[$parser]['ac'];
                        }
                        elseif ($name=='DOUBLE')
                        {
                              // we have a DOUBLE
                              // we must check that only 0123456789-.<space> are characters here
                              if (!ereg("^[+-]?[eE0123456789 \\t\\.]+$", $_xh[$parser]['ac']))
                              {
                                    // TODO: find a better way of throwing an error
                                    // than this!
                                    error_log('XML-RPC: non numeric value received in DOUBLE: '.$_xh[$parser]['ac']);
                                    //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";
                                    $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';
                              }
                              else
                              {
                                    // it's ok, add it on
                                    //$_xh[$parser]['st'].=(double)$_xh[$parser]['ac'];
                                    $_xh[$parser]['value']=(double)$_xh[$parser]['ac'];
                              }
                        }
                        else
                        {
                              // we have an I4/INT
                              // we must check that only 0123456789-<space> are characters here
                              if (!ereg("^[+-]?[0123456789 \\t]+$", $_xh[$parser]['ac']))
                              {
                                    // TODO: find a better way of throwing an error
                                    // than this!
                                    error_log('XML-RPC: non numeric value received in INT: '.$_xh[$parser]['ac']);
                                    //$_xh[$parser]['st'].="'ERROR_NON_NUMERIC_FOUND'";
                                    $_xh[$parser]['value']='ERROR_NON_NUMERIC_FOUND';
                              }
                              else
                              {
                                    // it's ok, add it on
                                    //$_xh[$parser]['st'].=(int)$_xh[$parser]['ac'];
                                    $_xh[$parser]['value']=(int)$_xh[$parser]['ac'];
                              }
                        }
                        $_xh[$parser]['ac']='';
                        //$_xh[$parser]['qt']=0;
                        $_xh[$parser]['lv']=3; // indicate we've found a value
                        break;
                  case 'VALUE':
                        // This if() detects if no scalar was inside <VALUE></VALUE>
                        if ($_xh[$parser]['vt']=='value')
                        {
                              $_xh[$parser]['value']=$_xh[$parser]['ac'];
                              $_xh[$parser]['vt']=$xmlrpcString;
                        }
                        /*if (strlen($_xh[$parser]['ac'])>0 &&
                              $_xh[$parser]['vt']==$xmlrpcString)
                        {
                              $_xh[$parser]['st'].='"'. $_xh[$parser]['ac'] . '"';
                        }
                        // This if() detects if no scalar was inside <VALUE></VALUE>
                        // and pads an empty ''.
                        if($_xh[$parser]['st'][strlen($_xh[$parser]['st'])-1] == '(')
                        {
                              $_xh[$parser]['st'].= '""';
                        }
                        // G. Giunta 2005/03/12 save some chars in the reconstruction of string vals...
                        if ($_xh[$parser]['vt'] != $xmlrpcString)
                              $_xh[$parser]['st'].=", '" . $_xh[$parser]['vt'] . "')";
                        else
                              $_xh[$parser]['st'].=")";
                        if ($_xh[$parser]['cm'])
                        {
                              $_xh[$parser]['st'].=',';
                        }*/

                        // build the xmlrpc val out of the data received, and substitute it
                        $temp = new xmlrpcval($_xh[$parser]['value'], $_xh[$parser]['vt']);
                        // check if we are inside an array or struct:
                        // if value just built is inside an array, let's move it into array on the stack
                        if (count($_xh[$parser]['valuestack']) && $_xh[$parser]['valuestack'][0]['type']=='ARRAY')
                        {
                              $_xh[$parser]['valuestack'][0]['values'][] = $temp;
                        }
                        else
                        {
                        $_xh[$parser]['value'] = $temp;
                        }
                        break;
                  case 'MEMBER':
                        $_xh[$parser]['ac']='';
                        //$_xh[$parser]['qt']=0;
                        // add to array in the stack the last element built
                        // unless no VALUE was found
                        if ($_xh[$parser]['value'])
                              $_xh[$parser]['valuestack'][0]['values'][$_xh[$parser]['valuestack'][0]['name']] = $_xh[$parser]['value'];
                        else
                              error_log('XML-RPC: missing VALUE inside STRUCT in received xml');
                        break;
                  case 'DATA':
                        $_xh[$parser]['ac']='';
                        //$_xh[$parser]['qt']=0;
                        break;
                  case 'PARAM':
                        //$_xh[$parser]['params'][]=$_xh[$parser]['st'];
                        if ($_xh[$parser]['value'])
                              $_xh[$parser]['params'][]=$_xh[$parser]['value'];
                        else
                              error_log('XML-RPC: missing VALUE inside PARAM in received xml');
                        break;
                  case 'METHODNAME':
                        $_xh[$parser]['method']=ereg_replace("^[\n\r\t ]+", '', $_xh[$parser]['ac']);
                        break;
                  case 'PARAMS':
                  case 'FAULT':
                  case 'METHODCALL':
                  case 'METHORESPONSE':
                        break;
                  default:
                        // End of INVALID ELEMENT!
                        // shall we add an assert here for unreachable code???
                        break;
            }

            // if it's a valid type name, set the type
            /*if (isset($xmlrpcTypes[strtolower($name)]))
            {
                  $_xh[$parser]['vt']=strtolower($name);
            }*/

            }

      }

      function xmlrpc_cd($parser, $data)
      {
            global $_xh, $xmlrpc_backslash;

            //if (ereg("^[\n\r \t]+$", $data)) return;
            // print "adding [${data}]\n";

            // skip processing if xml fault already detected
            if ($_xh[$parser]['isf'] < 2)
            {
                  if ($_xh[$parser]['lv']!=3)
                  {
                        // "lookforvalue==3" means that we've found an entire value
                        // and should discard any further character data
                        if ($_xh[$parser]['lv']==1)
                        {
                              // if we've found text and we're just in a <value> then
                              // turn quoting on, as this will be a string
                              //$_xh[$parser]['qt']=1;
                              // and say we've found a value
                              $_xh[$parser]['lv']=2;
                        }
                        if(!@isset($_xh[$parser]['ac']))
                        {
                              $_xh[$parser]['ac'] = '';
                        }
                        //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));
                        $_xh[$parser]['ac'].=$data;
                  }
            }
      }

      function xmlrpc_dh($parser, $data)
      {
            global $_xh, $xmlrpc_backslash;

            // skip processing if xml fault already detected
            if ($parser[$_xh]['isf'] < 2)
            {
                  if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';')
                  {
                        if ($_xh[$parser]['lv']==1)
                        {
                              //$_xh[$parser]['qt']=1;
                              $_xh[$parser]['lv']=2;
                        }
                        //$_xh[$parser]['ac'].=str_replace('$', '\$', str_replace('"', '\"', str_replace(chr(92),$xmlrpc_backslash, $data)));
                        $_xh[$parser]['ac'].=$data;
                  }
            }
      }

      /**
       * @package evocore
       * @subpackage xmlrpc
       */
      class xmlrpc_client
      {
            var $path;
            var $server;
            var $port;
            var $errno;
            var $errstr;
            var $debug=0;
            var $username='';
            var $password='';
            var $cert='';
            var $certpass='';
            var $verifypeer=1;
            var $verifyhost=1;
            var $no_multicall=false;

            function xmlrpc_client($path, $server, $port=0)
            {
                  $this->port=$port; $this->server=$server; $this->path=$path;
            }

            function setDebug($in)
            {
                  if ($in)
                  {
                        $this->debug=1;
                  }
                  else
                  {
                        $this->debug=0;
                  }
            }

            function setCredentials($u, $p)
            {
                  $this->username=$u;
                  $this->password=$p;
            }

            function setCertificate($cert, $certpass)
            {
                  $this->cert = $cert;
                  $this->certpass = $certpass;
            }

            function setSSLVerifyPeer($i)
            {
                  $this->verifypeer = $i;
            }

            function setSSLVerifyHost($i)
            {
                  $this->verifyhost = $i;
            }

            /*
             * xmlrpc_client->send(-)
             */
            function send($msg, $timeout=0, $method='http')
            {
                  if (is_array($msg))
                  {
                        // $msg is an array of xmlrpcmsg's
                        return $this->multicall($msg, $timeout, $method);
                  }

                  // where msg is an xmlrpcmsg
                  $msg->debug=$this->debug;

                  if ($method == 'https')
                  {
                        return $this->sendPayloadHTTPS($msg,
                        $this->server,
                        $this->port, $timeout,
                        $this->username, $this->password,
                        $this->cert,
                        $this->certpass);
                  }
                  else
                  {
                        return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
                        $timeout, $this->username,
                        $this->password);
                  }
            }

            function sendPayloadHTTP10($msg, $server, $port, $timeout=0,$username='', $password='')
            {
                  global $xmlrpcerr, $xmlrpcstr, $xmlrpcName, $xmlrpcVersion, $xmlrpc_defencoding;
                  if ($port==0)
                  {
                        $port=80;
                  }
                  if($timeout>0)
                  {
                        $fp=@fsockopen($server, $port,$this->errno, $this->errstr, $timeout);
                  }
                  else
                  {
                        $fp=@fsockopen($server, $port,$this->errno, $this->errstr);
                  }
                  if ($fp)
                  {
                        if ($timeout>0 && function_exists('stream_set_timeout'))
                              stream_set_timeout($fp, $timeout);
                  }
                  else
                  {
                        $this->errstr='Connect error';
                        $r=new xmlrpcresp(0, $xmlrpcerr['http_error'],$xmlrpcstr['http_error']);
                        return $r;
                  }
                  // Only create the payload if it was not created previously
                  if(empty($msg->payload))
                  {
                        $msg->createPayload();
                  }

                  // thanks to Grant Rauscher <grant7@firstworld.net>
                  // for this
                  $credentials='';
                  if ($username!='')
                  {
                        $credentials='Authorization: Basic ' . base64_encode($username . ':' . $password) . "\r\n";
                  }

                  $op= "POST " . $this->path. " HTTP/1.0\r\n" .
                        "User-Agent: " . $xmlrpcName . " " . $xmlrpcVersion . "\r\n" .
                        "Host: ". $server . "\r\n" .
                        $credentials .
                        "Accept-Charset: " . $xmlrpc_defencoding . "\r\n" .
                        "Content-Type: text/xml\r\nContent-Length: " .
                        strlen($msg->payload) . "\r\n\r\n" .
                        $msg->payload;

                  if (!fputs($fp, $op, strlen($op)))
                  {
                        $this->errstr='Write error';
                        $r=new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error']);
                        return $r;
                  }
                  $resp=$msg->parseResponseFile($fp);
                  fclose($fp);
                  return $resp;
            }

            // contributed by Justin Miller <justin@voxel.net>
            // requires curl to be built into PHP
            function sendPayloadHTTPS($msg, $server, $port, $timeout=0,$username='', $password='', $cert='',$certpass='')
            {
                  global $xmlrpcerr, $xmlrpcstr, $xmlrpcVersion, $xmlrpc_internalencoding;
                  if ($port == 0)
                  {
                        $port = 443;
                  }

                  // Only create the payload if it was not created previously
                  if(empty($msg->payload))
                  {
                        $msg->createPayload();
                  }

                  if (!function_exists('curl_init'))
                  {
                        $this->errstr='SSL unavailable on this install';
                        $r=new xmlrpcresp(0, $xmlrpcerr['no_ssl'], $xmlrpcstr['no_ssl']);
                        return $r;
                  }

                  $curl = curl_init('https://' . $server . ':' . $port . $this->path);

                  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                  // results into variable
                  if ($this->debug)
                  {
                        curl_setopt($curl, CURLOPT_VERBOSE, 1);
                  }
                  curl_setopt($curl, CURLOPT_USERAGENT, 'PHP XMLRPC '.$xmlrpcVersion);
                  // required for XMLRPC
                  curl_setopt($curl, CURLOPT_POST, 1);
                  // post the data
                  curl_setopt($curl, CURLOPT_POSTFIELDS, $msg->payload);
                  // the data
                  curl_setopt($curl, CURLOPT_HEADER, 1);
                  // return the header too
                  curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: text/xml', 'Accept-Charset: '.$xmlrpc_internalencoding));
                  // whether to verify remote host's cert
                  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verifypeer);
                  // whether to verify cert's common name (CN); 0 for no, 1 to verify that it exists, and 2 to verify that it matches the hostname used
                  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->verifyhost);
                  // required for XMLRPC
                  if ($timeout)
                  {
                        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout == 1 ? 1 : $timeout - 1);
                  }
                  // timeout is borked
                  if ($username && $password)
                  {
                        curl_setopt($curl, CURLOPT_USERPWD,"$username:$password");
                  }
                  // set auth stuff
                  if ($cert)
                  {
                        curl_setopt($curl, CURLOPT_SSLCERT, $cert);
                  }
                  // set cert file
                  if ($certpass)
                  {
                        curl_setopt($curl, CURLOPT_SSLCERTPASSWD,$certpass);
                  }
                  // set cert password

                  $result = curl_exec($curl);

                  if (!$result)
                  {
                        $this->errstr='no response';
                        $resp=new xmlrpcresp(0, $xmlrpcerr['curl_fail'], $xmlrpcstr['curl_fail']. ': '. curl_error($curl));
                        curl_close($curl);
                  }
                  else
                  {
                        curl_close($curl);
                        $resp = $msg->parseResponse($result);
                  }
                  return $resp;
            }

            function multicall($msgs, $timeout=0, $method='http')
            {
                  $results = false;

                  if (! $this->no_multicall)
                  {
                        $results = $this->_try_multicall($msgs, $timeout, $method);
                        /* TODO - this is not php3-friendly */
                        // if($results !== false)
                        if(is_array($results))
                        {
                              // Either the system.multicall succeeded, or the send
                              // failed (e.g. due to HTTP timeout). In either case,
                              // we're done for now.
                              return $results;
                        }
                        else
                        {
                              // system.multicall unsupported by server,
                              // don't try it next time...
                              $this->no_multicall = true;
                        }
                  }

                  // system.multicall is unupported by server:
                  //   Emulate multicall via multiple requests
                  $results = array();
                  //foreach($msgs as $msg)
                  @reset($msgs);
                  while(list(,$msg) = @each($msgs))
                  {
                        $results[] = $this->send($msg, $timeout, $method);
                  }
                  return $results;
            }

            // Attempt to boxcar $msgs via system.multicall.
            function _try_multicall($msgs, $timeout, $method)
            {
                  // Construct multicall message
                  $calls = array();
                  //foreach($msgs as $msg)
                  @reset($msgs);
                  while(list(,$msg) = @each($msgs))
                  {
                        $call['methodName'] = new xmlrpcval($msg->method(),'string');
                        $numParams = $msg->getNumParams();
                        $params = array();
                        for ($i = 0; $i < $numParams; $i++)
                        {
                              $params[$i] = $msg->getParam($i);
                        }
                        $call['params'] = new xmlrpcval($params, 'array');
                        $calls[] = new xmlrpcval($call, 'struct');
                  }
                  $multicall = new xmlrpcmsg('system.multicall');
                  $multicall->addParam(new xmlrpcval($calls, 'array'));

                  // Attempt RPC call
                  $result = $this->send($multicall, $timeout, $method);
                  if(!is_object($result))
                  {
                        return ($result || 0); // transport failed
                  }

                  if($result->faultCode() != 0)
                  {
                        return false;           // system.multicall failed
                  }

                  // Unpack responses.
                  $rets = $result->value();
                  if($rets->kindOf() != 'array')
                  {
                        return false;           // bad return type from system.multicall
                  }
                  $numRets = $rets->arraysize();
                  if($numRets != count($msgs))
                  {
                        return false;           // wrong number of return values.
                  }

                  $response = array();
                  for ($i = 0; $i < $numRets; $i++)
                  {
                        $val = $rets->arraymem($i);
                        switch ($val->kindOf())
                        {
                        case 'array':
                              if($val->arraysize() != 1)
                              {
                                    return false;           // Bad value
                              }
                              // Normal return value
                              $response[$i] = new xmlrpcresp($val->arraymem(0));
                              break;
                        case 'struct':
                              $code = $val->structmem('faultCode');
                              if($code->kindOf() != 'scalar' || $code->scalartyp() != 'int')
                              {
                                    return false;
                              }
                              $str = $val->structmem('faultString');
                              if($str->kindOf() != 'scalar' || $str->scalartyp() != 'string')
                              {
                                    return false;
                              }
                              $response[$i] = new xmlrpcresp(0, $code->scalarval(), $str->scalarval());
                              break;
                        default:
                              return false;
                        }
                  }
                  return $response;
            }
      } // end class xmlrpc_client

      /**
       * @package evocore
       * @subpackage xmlrpc
       */
      class xmlrpcresp
      {
            var $val = 0;
            var $errno = 0;
            var $errstr = '';
            var $hdrs = array();

            function xmlrpcresp($val, $fcode = 0, $fstr = '')
            {
                  if ($fcode != 0)
                  {
                        // error
                        $this->errno = $fcode;
                        $this->errstr = $fstr;
                        //$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later.
                  }
                  elseif (!is_object($val))
                  {
                        // programmer error
                        error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to xmlrpcresp. Defaulting to empty value.");
                        $this->val = new xmlrpcval();
                  }
                  else
                  {
                        // success
                        $this->val = $val;
                  }
            }

            function faultCode()
            {
                  return $this->errno;
            }

            function faultString()
            {
                  return $this->errstr;
            }

            function value()
            {
                  return $this->val;
            }

            function serialize()
            {
                  $result = "<methodResponse>\n";
                  if ($this->errno)
                  {
                        // G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
                        $result .= '<fault>
      <value>
            <struct>
                  <member>
                        <name>faultCode</name>
                        <value><int>' . $this->errno . '</int></value>
                  </member>
                  <member>
                        <name>faultString</name>
                        <value><string>' . xmlrpc_encode_entitites($this->errstr) . '</string></value>
                  </member>
            </struct>
      </value>
</fault>';
                  }
                  else
                  {
                        $result .= "<params>\n<param>\n" .
                              $this->val->serialize() .
                              "</param>\n</params>";
                  }
                  $result .= "\n</methodResponse>";
                  logIO("O",$result);
                  return $result;
            }
      }

      /**
       * @package evocore
       * @subpackage xmlrpc
       */
      class xmlrpcmsg
      {
            var $payload;
            var $methodname;
            var $params=array();
            var $debug=0;

            function xmlrpcmsg($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()
            {
                  // TODO: handle encoding
                  // return "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">\n<methodCall>\n";

                  return "<?xml version=\"1.0\"?" . ">\n<methodCall>\n";
            }

            function xml_footer()
            {
                  return "</methodCall>\n";
            }

            function createPayload()
            {
                  $this->payload=$this->xml_header();
                  $this->payload.='<methodName>' . $this->methodname . "</methodName>\n";
                  //    if (sizeof($this->params)) {
                  $this->payload.="<params>\n";
                  for($i=0; $i<sizeof($this->params); $i++)
                  {
                        $p=$this->params[$i];
                        $this->payload.="<param>\n" . $p->serialize() .
                        "</param>\n";
                  }
                  $this->payload.="</params>\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();
                  logIO("O",$this->payload);
                  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 $_xh,$xmlrpcerr,$xmlrpcstr;
                  global $xmlrpc_defencoding, $xmlrpc_internalencoding;

                  $hdrfnd = 0;
                  if($this->debug)
                  {
                        //by maHo, replaced htmlspecialchars with htmlentities
                        print "<PRE>---GOT---\n" . htmlentities($data) . "\n---END---\n</PRE>";
                  }

                  if($data == '')
                  {
                        error_log('No response received from server.');
                        $r = new xmlrpcresp(0, $xmlrpcerr['no_data'], $xmlrpcstr['no_data']);
                        return $r;
                  }
                  // 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))
                  {
                        // Strip HTTP 1.1 100 Continue header if present
                        while (ereg('^HTTP/1.1 1[0-9]{2}', $data))
                        {
                              $pos = strpos($data, 'HTTP', 12);
                              // server sent a Continue header without any (valid) content following...
                              // give the client a chance to know it
                              if (!$pos && !is_int($pos)) // works fine in php 3, 4 and 5
                                    break;
                              $data = substr($data, $pos);
                        }
                        if (!ereg("^HTTP/[0-9\\.]+ 200 ", $data))
                        {
                              $errstr= substr($data, 0, strpos($data, "\n")-1);
                              error_log('HTTP error, got response: ' .$errstr);
                              $r=new xmlrpcresp(0, $xmlrpcerr['http_error'], $xmlrpcstr['http_error']. ' (' . $errstr . ')');
                              return $r;
                        }
                  }
                  $parser = xml_parser_create($xmlrpc_defencoding);

                  // G. Giunta 2004/04/06
                  // Clean up the accumulator, or it will grow indefinitely long
                  // if making xmlrpc calls for a while
                  $_xh=array();
                  $_xh[$parser]=array();
                  $_xh[$parser]['headers'] = array();
                  $_xh[$parser]['stack'] = array();
                  $_xh[$parser]['valuestack'] = array();

                  // separate HTTP headers from data
                  if (ereg("^HTTP", $data))
                  {
                        // be tolerant to usage of \n instead of \r\n to separate headers and data
                        // (even though it is not valid http)
                        $pos = strpos($data,"\r\n\r\n");
                        if($pos || is_int($pos))
                              $bd = $pos+4;
                        else
                        {
                              $pos = strpos($data,"\n\n");
                              if($pos || is_int($pos))
                                    $bd = $pos+2;
                              else
                              {
                                    // No separation between response headers and body: fault?
                                    $bd = 0;
                              }
                        }
                        // be tolerant to line endings, and extra empty lines
                        $ar = split("\r?\n", trim(substr($data, 0, $pos)));
                        while (list(,$line) = @each($ar))
                        {
                              // take care of multi-line headers
                              $arr = explode(':',$line);
                              if(count($arr) > 1)
                              {
                                    $header_name = trim($arr[0]);
                                    // TO DO: some headers (the ones that allow a CSV list of values)
                                    // do allow many values to be passed using multiple header lines.
                                    // We should add content to $_xh[$parser]['headers'][$header_name]
                                    // instead of replacing it for those...
                                    $_xh[$parser]['headers'][$header_name] = $arr[1];
                                    for ($i = 2; $i < count($arr); $i++)
                                    {
                                          $_xh[$parser]['headers'][$header_name] .= ':'.$arr[$i];
                                    } // while
                                    $_xh[$parser]['headers'][$header_name] = trim($_xh[$parser]['headers'][$header_name]);
                              } else if (isset($header_name))
                              {
                                    $_xh[$parser]['headers'][$header_name] .= ' ' . trim($line);
                              }
                        }
                        $data = substr($data, $bd);

                        if ($this->debug && count($_xh[$parser]['headers']))
                        {
                              print '<PRE>';
                              //foreach ($_xh[$parser]['headers'] as $header)
                              @reset($_xh[$parser]['headers']);
                              while(list($header, $value) = @each($_xh[$parser]['headers']))
                              {
                                    print "HEADER: $header: $value\n";
                              }
                              print "</PRE>\n";
                        }
                  }

                  // be tolerant of extra whitespace in response body
                  $data = trim($data);

                  // be tolerant of junk after methodResponse (e.g. javascript automatically inserted by free hosts)
                  // idea from Luca Mariano <luca.mariano@email.it> originally in PEARified version of the lib
                  $bd = false;
                  $pos = strpos($data, "</methodResponse>");
                  while ($pos || is_int($pos))
                  {
                        $bd = $pos+17;
                        $pos = strpos($data, "</methodResponse>", $bd);
                  }
                  if ($bd)
                        $data = substr($data, 0, $bd);

                  //$_xh[$parser]['st']='';
                  //$_xh[$parser]['cm']=0;
                  $_xh[$parser]['isf']=0;
                  $_xh[$parser]['isf_reason']=0;
                  $_xh[$parser]['ac']='';
                  //$_xh[$parser]['qt']='';

                  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
                  // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
                  // the xml parser to give us back data in the expected charset
                  xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $xmlrpc_internalencoding);

                  xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
                  xml_set_character_data_handler($parser, 'xmlrpc_cd');
                  xml_set_default_handler($parser, 'xmlrpc_dh');
                  //$xmlrpc_value=new xmlrpcval;

                  if (!xml_parse($parser, $data, sizeof($data)))
                  {
                        // thanks to Peter Kocks <peter.kocks@baygate.com>
                        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 xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return'].' ('.$errstr.')');
                        xml_parser_free($parser);
                        if ($this->debug)
                              echo $errstr;
                        $r->hdrs = $_xh[$parser]['headers'];
                        return $r;
                  }
                  xml_parser_free($parser);

                  if ($_xh[$parser]['isf'] > 1)
                  {
                        if ($this->debug)
                        {
                              ///@todo echo something for user?
                        }

                        $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'],
                        $xmlrpcstr['invalid_return'] . ' ' . $_xh[$parser]['isf_reason']);
                  }
                  //else if (strlen($_xh[$parser]['st'])==0)
                  else if (!is_object($_xh[$parser]['value']))
                  {
                        // then something odd has happened
                        // and it's time to generate a client side error
                        // indicating something odd went on
                        $r=new xmlrpcresp(0, $xmlrpcerr['invalid_return'],
                        $xmlrpcstr['invalid_return']);
                  }
                  else
                  {

                        if ($this->debug)
                        {
                              //print "<PRE>---EVALING---[" .
                              //strlen($_xh[$parser]['st']) . " chars]---\n" .
                              //htmlspecialchars($_xh[$parser]['st']) . ";\n---END---</PRE>";
                              print "<PRE>---PARSED---\n" ;
                              var_dump($_xh[$parser]['value']);
                              print "\n---END---</PRE>";
                        }

                        //$allOK=0;
                        //@eval('$v=' . $_xh[$parser]['st'] . '; $allOK=1;');
                        //if (!$allOK)
                        //{
                        //    $r = new xmlrpcresp(0, $xmlrpcerr['invalid_return'], $xmlrpcstr['invalid_return']);
                        //}
                        //else
                        $v = $_xh[$parser]['value'];
                        if ($_xh[$parser]['isf'])
                        {
                              $errno_v = $v->structmem('faultCode');
                              $errstr_v = $v->structmem('faultString');
                              $errno = $errno_v->scalarval();

                              if ($errno == 0)
                              {
                                    // FAULT returned, errno needs to reflect that
                                    $errno = -1;
                              }

                              $r = new xmlrpcresp($v, $errno, $errstr_v->scalarval());
                        }
                        else
                        {
                              $r=new xmlrpcresp($v);
                        }
                  }

                  $r->hdrs = $_xh[$parser]['headers'];
                  return $r;
            }
      }

      /**
       * @package evocore
       * @subpackage xmlrpc
       */
      class xmlrpcval
      {
            var $me=array();
            var $mytype=0;

            /*
             * Type will default to string
             */
            function xmlrpcval($val=-1, $type='')
            {
                  global $xmlrpcTypes;
                  $this->me=array();
                  $this->mytype=0;
                  if ($val!=-1 || !is_int($val) || $type!='')
                  {
                        if ($type=='')
                        {
                              $type='string';
                        }
                        if ($xmlrpcTypes[$type]==1)
                        {
                              $this->addScalar($val,$type);
                        }
                        elseif ($xmlrpcTypes[$type]==2)
                        {
                              $this->addArray($val);
                        }
                        elseif ($xmlrpcTypes[$type]==3)
                        {
                              $this->addStruct($val);
                        }
                  }
            }

            function addScalar($val, $type='string')
            {
                  global $xmlrpcTypes, $xmlrpcBoolean;

                  if ($this->mytype==1)
                  {
                        echo '<strong>xmlrpcval</strong>: scalar can have only one value<br />';
                        return 0;
                  }
                  $typeof=$xmlrpcTypes[$type];
                  if ($typeof!=1)
                  {
                        echo '<strong>xmlrpcval</strong>: not a scalar type (${typeof})<br />';
                        return 0;
                  }

                  if ($type==$xmlrpcBoolean)
                  {
                        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 xmlrpcval($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 $xmlrpcTypes;
                  if ($this->mytype!=0)
                  {
                        echo '<strong>xmlrpcval</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
                        return 0;
                  }

                  $this->mytype=$xmlrpcTypes['array'];
                  $this->me['array']=$vals;
                  return 1;
            }

            function addStruct($vals)
            {
                  global $xmlrpcTypes;
                  if ($this->mytype!=0)
                  {
                        echo '<strong>xmlrpcval</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
                        return 0;
                  }
                  $this->mytype=$xmlrpcTypes['struct'];
                  $this->me['struct']=$vals;
                  return 1;
            }

            function dump($ar)
            {
                  reset($ar);
                  while ( list( $key, $val ) = each( $ar ) )
                  {
                        echo "$key => $val<br />";
                        if ($key == 'array')
                        {
                              while ( list( $key2, $val2 ) = each( $val ) )
                              {
                                    echo "-- $key2 => $val2<br />";
                              }
                        }
                  }
            }

            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 $xmlrpcTypes, $xmlrpcBase64, $xmlrpcString,
                  $xmlrpcBoolean;
                  switch(@$xmlrpcTypes[$typ])
                  {
                        case 3:
                              // struct
                              $rs.="<struct>\n";
                              reset($val);
                              while(list($key2, $val2)=each($val))
                              {
                                    $rs.="<member><name>${key2}</name>\n";
                                    $rs.=$this->serializeval($val2);
                                    $rs.="</member>\n";
                              }
                              $rs.='</struct>';
                              break;
                        case 2:
                              // array
                              $rs.="<array>\n<data>\n";
                              for($i=0; $i<sizeof($val); $i++)
                              {
                                    $rs.=$this->serializeval($val[$i]);
                              }
                              $rs.="</data>\n</array>";
                              break;
                        case 1:
                              switch ($typ)
                              {
                                    case $xmlrpcBase64:
                                          $rs.="<${typ}>" . base64_encode($val) . "</${typ}>";
                                          break;
                                    case $xmlrpcBoolean:
                                          $rs.="<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
                                          break;
                                    case $xmlrpcString:
                                          // G. Giunta 2005/2/13: do NOT use htmlentities, since
                                          // it will produce named html entities, which are invalid xml
                                          $rs.="<${typ}>" . xmlrpc_encode_entitites($val). "</${typ}>";
                                          // $rs.="<${typ}>" . htmlentities($val). "</${typ}>";
                                          break;
                                    default:
                                          $rs.="<${typ}>${val}</${typ}>";
                              }
                              break;
                        default:
                              break;
                  }
                  return $rs;
            }

            function serialize()
            {
                  return $this->serializeval($this);
            }

            function serializeval($o)
            {
                  //global $xmlrpcTypes;
                  $rs='';
                  $ar=$o->me;
                  reset($ar);
                  list($typ, $val) = each($ar);
                  $rs.='<value>';
                  $rs.=$this->serializedata($typ, $val);
                  $rs.="</value>\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 $xmlrpcBoolean, $xmlrpcBase64;
                  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))
                  {
                        @reset($b);
                        while(list($id,$cont) = @each($b))
                        {
                              $b[$id] = $cont->scalarval();
                        }
                  }

                  // add support for structures directly encoding php objects
                  if (is_object($b))
                  {
                        $t = get_object_vars($b);
                        @reset($t);
                        while(list($id,$cont) = @each($t))
                        {
                              $t[$id] = $cont->scalarval();
                        }
                        @reset($t);
                        while(list($id,$cont) = @each($t))
                        {
                              //eval('$b->'.$id.' = $cont;');
                              @$b->$id = $cont;
                        }
                  }
                  // end contrib
                  return $b;
            }

            function scalarval()
            {
                  //global $xmlrpcBoolean, $xmlrpcBase64;
                  reset($this->me);
                  list($a,$b)=each($this->me);
                  return $b;
            }

            function scalartyp()
            {
                  global $xmlrpcI4, $xmlrpcInt;
                  reset($this->me);
                  list($a,$b)=each($this->me);
                  if ($a==$xmlrpcI4)
                  {
                        $a=$xmlrpcInt;
                  }
                  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 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 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;
      }

      /****************************************************************
      * xmlrpc_decode takes a message in PHP xmlrpc object format and *
      * tranlates it into native PHP types.                           *
      *                                                               *
      * author: Dan Libby (dan@libby.com)                             *
      ****************************************************************/
      /*
       * evocore: We add xmlrpc_decode_recurse because the default PHP implementation
       * of xmlrpc_decode won't recurse! Bleh!
       * update: XML-RPC for PHP now copes with this, but we keep a stub for backward compatibility
       */
      function xmlrpc_decode_recurse($xmlrpc_val)
      {
            return php_xmlrpc_decode($xmlrpc_val);
      }

      function php_xmlrpc_decode($xmlrpc_val)
      {
            $kind = $xmlrpc_val->kindOf();

            if($kind == 'scalar')
            {
                  return $xmlrpc_val->scalarval();
            }
            elseif($kind == 'array')
            {
                  $size = $xmlrpc_val->arraysize();
                  $arr = array();

                  for($i = 0; $i < $size; $i++)
                  {
                        $arr[] = php_xmlrpc_decode($xmlrpc_val->arraymem($i));
                  }
                  return $arr;
            }
            elseif($kind == 'struct')
            {
                  $xmlrpc_val->structreset();
                  $arr = array();

                  while(list($key,$value)=$xmlrpc_val->structeach())
                  {
                        $arr[$key] = php_xmlrpc_decode($value);
                        // echo $key, '=>', $arr[$key], '<br />';
                  }
                  return $arr;
            }
      }

      if(function_exists('xmlrpc_decode'))
      {
            define('XMLRPC_EPI_ENABLED','1');
      }
      else
      {
            define('XMLRPC_EPI_ENABLED','0');
            function xmlrpc_decode($xmlrpc_val)
            {
                  $kind = $xmlrpc_val->kindOf();

                  if($kind == 'scalar')
                  {
                        return $xmlrpc_val->scalarval();
                  }
                  elseif($kind == 'array')
                  {
                        $size = $xmlrpc_val->arraysize();
                        $arr = array();

                        for($i = 0; $i < $size; $i++)
                        {
                              $arr[]=xmlrpc_decode($xmlrpc_val->arraymem($i));
                        }
                        return $arr;
                  }
                  elseif($kind == 'struct')
                  {
                        $xmlrpc_val->structreset();
                        $arr = array();

                        while(list($key,$value)=$xmlrpc_val->structeach())
                        {
                              $arr[$key] = xmlrpc_decode($value);
                        }
                        return $arr;
                  }
            }
      }

      /****************************************************************
      * xmlrpc_encode takes native php types and encodes them into    *
      * xmlrpc PHP object format.                                     *
      * BUG: All sequential arrays are turned into structs.  I don't  *
      * know of a good way to determine if an array is sequential     *
      * only.                                                         *
      *                                                               *
      * feature creep -- could support more types via optional type   *
      * argument.                                                     *
      *                                                               *
      * author: Dan Libby (dan@libby.com)                             *
      ****************************************************************/
      function php_xmlrpc_encode($php_val)
      {
            global $xmlrpcInt;
            global $xmlrpcDouble;
            global $xmlrpcString;
            global $xmlrpcArray;
            global $xmlrpcStruct;
            global $xmlrpcBoolean;

            $type = gettype($php_val);
            $xmlrpc_val = new xmlrpcval;

            switch($type)
            {
                  case 'array':
                  case 'object':
                        $arr = array();
                        while (list($k,$v) = each($php_val))
                        {
                              $arr[$k] = php_xmlrpc_encode($v);
                        }
                        $xmlrpc_val->addStruct($arr);
                        break;
                  case 'integer':
                        $xmlrpc_val->addScalar($php_val, $xmlrpcInt);
                        break;
                  case 'double':
                        $xmlrpc_val->addScalar($php_val, $xmlrpcDouble);
                        break;
                  case 'string':
                        $xmlrpc_val->addScalar($php_val, $xmlrpcString);
                        break;
                        // <G_Giunta_2001-02-29>
                        // Add support for encoding/decoding of booleans, since they are supported in PHP
                  case 'boolean':
                        $xmlrpc_val->addScalar($php_val, $xmlrpcBoolean);
                        break;
                        // </G_Giunta_2001-02-29>
                  // catch "resource", "NULL", "user function", "unknown type"
                  //case 'unknown type':
                  default:
                        // giancarlo pinerolo <ping@alt.it>
                        // it has to return
                        // an empty object in case (which is already
                        // at this point), not a boolean.
                        break;
                  }
                  return $xmlrpc_val;
      }

      if(XMLRPC_EPI_ENABLED == '0')
      {
            function xmlrpc_encode($php_val)
            {
                  global $xmlrpcInt;
                  global $xmlrpcDouble;
                  global $xmlrpcString;
                  global $xmlrpcArray;
                  global $xmlrpcStruct;
                  global $xmlrpcBoolean;

                  $type = gettype($php_val);
                  $xmlrpc_val = new xmlrpcval;

                  switch($type)
                  {
                        case 'array':
                        case 'object':
                              $arr = array();
                              while (list($k,$v) = each($php_val))
                              {
                                    $arr[$k] = xmlrpc_encode($v);
                              }
                              $xmlrpc_val->addStruct($arr);
                              break;
                        case 'integer':
                              $xmlrpc_val->addScalar($php_val, $xmlrpcInt);
                              break;
                        case 'double':
                              $xmlrpc_val->addScalar($php_val, $xmlrpcDouble);
                              break;
                        case 'string':
                              $xmlrpc_val->addScalar($php_val, $xmlrpcString);
                              break;
                              // <G_Giunta_2001-02-29>
                              // Add support for encoding/decoding of booleans, since they are supported in PHP
                        case 'boolean':
                              $xmlrpc_val->addScalar($php_val, $xmlrpcBoolean);
                              break;
                              // </G_Giunta_2001-02-29>
                        //case 'unknown type':
                        default:
                              // giancarlo pinerolo <ping@alt.it>
                              // it has to return
                              // an empty object in case (which is already
                              // at this point), not a boolean.
                              break;
                  }
                  return $xmlrpc_val;
            }
      }
?>

Generated by  Doxygen 1.6.0   Back to index