[2] | 1 | <?php |
---|
[5509] | 2 | /*************************************************************************** |
---|
| 3 | * Expresso Livre * |
---|
| 4 | * http://www.expressolivre.org * |
---|
| 5 | * -------------------------------------------- * |
---|
| 6 | * This program is free software; you can redistribute it and/or modify it * |
---|
| 7 | * under the terms of the GNU General Public License as published by the * |
---|
| 8 | * Free Software Foundation; either version 2 of the License, or (at your * |
---|
| 9 | * option) any later version. * |
---|
| 10 | \**************************************************************************/ |
---|
| 11 | |
---|
[2] | 12 | // by Edd Dumbill (C) 1999-2001 |
---|
| 13 | // <edd@usefulinc.com> |
---|
| 14 | // xmlrpc.inc,v 1.18 2001/07/06 18:23:57 edmundd |
---|
| 15 | |
---|
| 16 | // License is granted to use or modify this software ("XML-RPC for PHP") |
---|
| 17 | // for commercial or non-commercial use provided the copyright of the author |
---|
| 18 | // is preserved in any distributed or derivative work. |
---|
| 19 | |
---|
| 20 | // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR |
---|
| 21 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
---|
| 22 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
---|
| 23 | // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
---|
| 24 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
---|
| 25 | // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
---|
| 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
---|
| 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
| 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
---|
| 29 | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 30 | |
---|
| 31 | |
---|
| 32 | if (!function_exists('xml_parser_create')) |
---|
| 33 | { |
---|
| 34 | // Win 32 fix. From: "Leo West" <lwest@imaginet.fr> |
---|
| 35 | if($WINDIR) |
---|
| 36 | { |
---|
| 37 | dl('php3_xml.dll'); |
---|
| 38 | } |
---|
| 39 | else |
---|
| 40 | { |
---|
| 41 | dl('xml.so'); |
---|
| 42 | } |
---|
| 43 | } |
---|
| 44 | |
---|
| 45 | define('xmlrpcI4','i4'); |
---|
| 46 | define('xmlrpcInt','int'); |
---|
| 47 | define('xmlrpcBoolean','boolean'); |
---|
| 48 | define('xmlrpcDouble','double'); |
---|
| 49 | define('xmlrpcString','string'); |
---|
| 50 | define('xmlrpcDateTime','dateTime.iso8601'); |
---|
| 51 | define('xmlrpcBase64','base64'); |
---|
| 52 | define('xmlrpcArray','array'); |
---|
| 53 | define('xmlrpcStruct','struct'); |
---|
| 54 | |
---|
| 55 | $GLOBALS['xmlrpcTypes'] = array( |
---|
| 56 | xmlrpcI4 => 1, |
---|
| 57 | xmlrpcInt => 1, |
---|
| 58 | xmlrpcBoolean => 1, |
---|
| 59 | xmlrpcString => 1, |
---|
| 60 | xmlrpcDouble => 1, |
---|
| 61 | xmlrpcDateTime => 1, |
---|
| 62 | xmlrpcBase64 => 1, |
---|
| 63 | xmlrpcArray => 2, |
---|
| 64 | xmlrpcStruct => 3 |
---|
| 65 | ); |
---|
| 66 | |
---|
| 67 | $GLOBALS['xmlEntities']=array( |
---|
| 68 | 'amp' => '&', |
---|
| 69 | 'quot' => '"', |
---|
| 70 | 'lt' => '<', |
---|
| 71 | 'gt' => '>', |
---|
| 72 | 'apos' => "'" |
---|
| 73 | ); |
---|
| 74 | |
---|
| 75 | $GLOBALS['xmlrpcerr']['unknown_method'] = 1; |
---|
| 76 | $GLOBALS['xmlrpcstr']['unknown_method'] = 'Unknown method'; |
---|
| 77 | $GLOBALS['xmlrpcerr']['invalid_return'] = 2; |
---|
| 78 | $GLOBALS['xmlrpcstr']['invalid_return'] = 'Invalid return payload: enabling debugging to examine incoming payload'; |
---|
| 79 | $GLOBALS['xmlrpcerr']['incorrect_params'] = 3; |
---|
| 80 | $GLOBALS['xmlrpcstr']['incorrect_params'] = 'Incorrect parameters passed to method'; |
---|
| 81 | $GLOBALS['xmlrpcerr']['introspect_unknown'] = 4; |
---|
| 82 | $GLOBALS['xmlrpcstr']['introspect_unknown'] = "Can't introspect: method unknown"; |
---|
| 83 | $GLOBALS['xmlrpcerr']['http_error'] = 5; |
---|
| 84 | $GLOBALS['xmlrpcstr']['http_error'] = "Didn't receive 200 OK from remote server."; |
---|
| 85 | $GLOBALS['xmlrpcerr']['no_data'] = 6; |
---|
| 86 | $GLOBALS['xmlrpcstr']['no_data'] = 'No data received from server.'; |
---|
| 87 | $GLOBALS['xmlrpcerr']['no_ssl'] = 7; |
---|
| 88 | $GLOBALS['xmlrpcstr']['no_ssl'] = 'No SSL support compiled in.'; |
---|
| 89 | $GLOBALS['xmlrpcerr']['curl_fail'] = 8; |
---|
| 90 | $GLOBALS['xmlrpcstr']['curl_fail'] = 'CURL error'; |
---|
| 91 | $GLOBALS['xmlrpcerr']['no_access'] = 9; |
---|
| 92 | $GLOBALS['xmlrpcstr']['no_access'] = 'Access denied'; |
---|
| 93 | $GLOBALS['xmlrpcerr']['not_existent'] = 10; |
---|
| 94 | $GLOBALS['xmlrpcstr']['not_existent'] = 'Entry does not (longer) exist!'; |
---|
| 95 | |
---|
| 96 | $GLOBALS['xmlrpc_defencoding'] = 'UTF-8'; |
---|
| 97 | |
---|
| 98 | $GLOBALS['xmlrpcName'] = 'XML-RPC for PHP'; |
---|
| 99 | $GLOBALS['xmlrpcVersion'] = '1.0b9'; |
---|
| 100 | |
---|
| 101 | // let user errors start at 800 |
---|
| 102 | $GLOBALS['xmlrpcerruser'] = 800; |
---|
| 103 | // let XML parse errors start at 100 |
---|
| 104 | $GLOBALS['xmlrpcerrxml'] = 100; |
---|
| 105 | |
---|
| 106 | // formulate backslashes for escaping regexp |
---|
| 107 | $GLOBALS['xmlrpc_backslash'] = chr(92) . chr(92); |
---|
| 108 | |
---|
| 109 | /*! |
---|
| 110 | @function xmlrpcfault |
---|
| 111 | @abstract Error reporting for XML-RPC |
---|
| 112 | @discussion Author: jengo <br> |
---|
| 113 | Returns XML-RPC fault and stops this execution of the application. <br> |
---|
| 114 | Syntax: void xmlrpcfault(string) <br> |
---|
| 115 | Example1: xmlrpcfault('Session could not be verifed'); <br> |
---|
| 116 | @param $string Error message to be returned. |
---|
| 117 | */ |
---|
| 118 | function xmlrpcfault($string) |
---|
| 119 | { |
---|
| 120 | $r = CreateObject('phpgwapi.xmlrpcresp', |
---|
| 121 | CreateObject('phpgwapi.xmlrpcval'), |
---|
| 122 | $GLOBALS['xmlrpcerr']['unknown_method'], |
---|
| 123 | $string |
---|
| 124 | ); |
---|
| 125 | $payload = '<?xml version="1.0"?>' . "\n" . $r->serialize(); |
---|
| 126 | Header('Content-type: text/xml'); |
---|
| 127 | Header('Content-length: ' . strlen($payload)); |
---|
| 128 | print $payload; |
---|
| 129 | $GLOBALS['phpgw']->common->phpgw_exit(False); |
---|
| 130 | } |
---|
| 131 | |
---|
| 132 | // used to store state during parsing |
---|
| 133 | // quick explanation of components: |
---|
| 134 | // st - used to build up a string for evaluation |
---|
| 135 | // ac - used to accumulate values |
---|
| 136 | // qt - used to decide if quotes are needed for evaluation |
---|
| 137 | // cm - used to denote struct or array (comma needed) |
---|
| 138 | // isf - used to indicate a fault |
---|
| 139 | // lv - used to indicate "looking for a value": implements |
---|
| 140 | // the logic to allow values with no types to be strings |
---|
| 141 | // params - used to store parameters in method calls |
---|
| 142 | // method - used to store method name |
---|
| 143 | |
---|
| 144 | $GLOBALS['_xh']=array(); |
---|
| 145 | |
---|
| 146 | function xmlrpc_entity_decode($string) |
---|
| 147 | { |
---|
[6057] | 148 | $top = preg_split('/&/', $string); |
---|
[2] | 149 | $op = ''; |
---|
| 150 | $i = 0; |
---|
| 151 | while($i<sizeof($top)) |
---|
| 152 | { |
---|
[5912] | 153 | if (preg_match('/^([#a-zA-Z0-9]+);/', $top[$i], $regs)) |
---|
[2] | 154 | { |
---|
[5934] | 155 | $op .= preg_replace('/^[#a-zA-Z0-9]+;/', |
---|
[2] | 156 | xmlrpc_lookup_entity($regs[1]), $top[$i]); |
---|
| 157 | } |
---|
| 158 | else |
---|
| 159 | { |
---|
| 160 | if ($i == 0) |
---|
| 161 | { |
---|
| 162 | $op = $top[$i]; |
---|
| 163 | } |
---|
| 164 | else |
---|
| 165 | { |
---|
| 166 | $op .= '&' . $top[$i]; |
---|
| 167 | } |
---|
| 168 | } |
---|
[7655] | 169 | ++$i; |
---|
[2] | 170 | } |
---|
| 171 | return $op; |
---|
| 172 | } |
---|
| 173 | |
---|
| 174 | function xmlrpc_lookup_entity($ent) |
---|
| 175 | { |
---|
| 176 | if (isset($GLOBALS['xmlEntities'][strtolower($ent)])) |
---|
| 177 | { |
---|
| 178 | return $GLOBALS['xmlEntities'][strtolower($ent)]; |
---|
| 179 | } |
---|
[5912] | 180 | if (preg_match('/^#([0-9]+)$/', $ent, $regs)) |
---|
[2] | 181 | { |
---|
| 182 | return chr($regs[1]); |
---|
| 183 | } |
---|
| 184 | return '?'; |
---|
| 185 | } |
---|
| 186 | |
---|
| 187 | function xmlrpc_se($parser, $name, $attrs) |
---|
| 188 | { |
---|
| 189 | switch($name) |
---|
| 190 | { |
---|
| 191 | case 'STRUCT': |
---|
| 192 | case 'ARRAY': |
---|
| 193 | $GLOBALS['_xh'][$parser]['st'] .= 'array('; |
---|
| 194 | $GLOBALS['_xh'][$parser]['cm']++; |
---|
| 195 | // this last line turns quoting off |
---|
| 196 | // this means if we get an empty array we'll |
---|
| 197 | // simply get a bit of whitespace in the eval |
---|
| 198 | $GLOBALS['_xh'][$parser]['qt']=0; |
---|
| 199 | break; |
---|
| 200 | case 'NAME': |
---|
| 201 | $GLOBALS['_xh'][$parser]['st'] .= "'"; |
---|
| 202 | $GLOBALS['_xh'][$parser]['ac'] = ''; |
---|
| 203 | break; |
---|
| 204 | case 'FAULT': |
---|
| 205 | $GLOBALS['_xh'][$parser]['isf'] = 1; |
---|
| 206 | break; |
---|
| 207 | case 'PARAM': |
---|
| 208 | $GLOBALS['_xh'][$parser]['st'] = ''; |
---|
| 209 | break; |
---|
| 210 | case 'VALUE': |
---|
| 211 | $GLOBALS['_xh'][$parser]['st'] .= " CreateObject('phpgwapi.xmlrpcval',"; |
---|
| 212 | $GLOBALS['_xh'][$parser]['vt'] = xmlrpcString; |
---|
| 213 | $GLOBALS['_xh'][$parser]['ac'] = ''; |
---|
| 214 | $GLOBALS['_xh'][$parser]['qt'] = 0; |
---|
| 215 | $GLOBALS['_xh'][$parser]['lv'] = 1; |
---|
| 216 | // look for a value: if this is still 1 by the |
---|
| 217 | // time we reach the first data segment then the type is string |
---|
| 218 | // by implication and we need to add in a quote |
---|
| 219 | break; |
---|
| 220 | case 'I4': |
---|
| 221 | case 'INT': |
---|
| 222 | case 'STRING': |
---|
| 223 | case 'BOOLEAN': |
---|
| 224 | case 'DOUBLE': |
---|
| 225 | case 'DATETIME.ISO8601': |
---|
| 226 | case 'BASE64': |
---|
| 227 | $GLOBALS['_xh'][$parser]['ac']=''; // reset the accumulator |
---|
| 228 | |
---|
| 229 | if ($name=='DATETIME.ISO8601' || $name=='STRING') |
---|
| 230 | { |
---|
| 231 | $GLOBALS['_xh'][$parser]['qt']=1; |
---|
| 232 | if ($name=='DATETIME.ISO8601') |
---|
| 233 | { |
---|
| 234 | $GLOBALS['_xh'][$parser]['vt']=xmlrpcDateTime; |
---|
| 235 | } |
---|
| 236 | } |
---|
| 237 | elseif($name=='BASE64') |
---|
| 238 | { |
---|
| 239 | $GLOBALS['_xh'][$parser]['qt']=2; |
---|
| 240 | } |
---|
| 241 | else |
---|
| 242 | { |
---|
| 243 | // No quoting is required here -- but |
---|
| 244 | // at the end of the element we must check |
---|
| 245 | // for data format errors. |
---|
| 246 | $GLOBALS['_xh'][$parser]['qt']=0; |
---|
| 247 | } |
---|
| 248 | break; |
---|
| 249 | case 'MEMBER': |
---|
| 250 | $GLOBALS['_xh'][$parser]['ac']=''; |
---|
| 251 | break; |
---|
| 252 | default: |
---|
| 253 | break; |
---|
| 254 | } |
---|
| 255 | |
---|
| 256 | if ($name!='VALUE') |
---|
| 257 | { |
---|
| 258 | $GLOBALS['_xh'][$parser]['lv']=0; |
---|
| 259 | } |
---|
| 260 | } |
---|
| 261 | |
---|
| 262 | function xmlrpc_ee($parser, $name) |
---|
| 263 | { |
---|
| 264 | switch($name) |
---|
| 265 | { |
---|
| 266 | case 'STRUCT': |
---|
| 267 | case 'ARRAY': |
---|
| 268 | if ($GLOBALS['_xh'][$parser]['cm'] && substr($GLOBALS['_xh'][$parser]['st'], -1) ==',') |
---|
| 269 | { |
---|
| 270 | $GLOBALS['_xh'][$parser]['st']=substr($GLOBALS['_xh'][$parser]['st'],0,-1); |
---|
| 271 | } |
---|
| 272 | $GLOBALS['_xh'][$parser]['st'].=')'; |
---|
| 273 | $GLOBALS['_xh'][$parser]['vt']=strtolower($name); |
---|
| 274 | $GLOBALS['_xh'][$parser]['cm']--; |
---|
| 275 | break; |
---|
| 276 | case 'NAME': |
---|
| 277 | $GLOBALS['_xh'][$parser]['st'].= $GLOBALS['_xh'][$parser]['ac'] . "' => "; |
---|
| 278 | break; |
---|
| 279 | case 'BOOLEAN': |
---|
| 280 | // special case here: we translate boolean 1 or 0 into PHP |
---|
| 281 | // constants true or false |
---|
| 282 | if ($GLOBALS['_xh'][$parser]['ac']=='1') |
---|
| 283 | { |
---|
| 284 | $GLOBALS['_xh'][$parser]['ac']='True'; |
---|
| 285 | } |
---|
| 286 | else |
---|
| 287 | { |
---|
| 288 | $GLOBALS['_xh'][$parser]['ac']='false'; |
---|
| 289 | } |
---|
| 290 | $GLOBALS['_xh'][$parser]['vt']=strtolower($name); |
---|
| 291 | // Drop through intentionally. |
---|
| 292 | case 'I4': |
---|
| 293 | case 'INT': |
---|
| 294 | case 'STRING': |
---|
| 295 | case 'DOUBLE': |
---|
| 296 | case 'DATETIME.ISO8601': |
---|
| 297 | case 'BASE64': |
---|
| 298 | if ($GLOBALS['_xh'][$parser]['qt']==1) |
---|
| 299 | { |
---|
| 300 | // we use double quotes rather than single so backslashification works OK |
---|
| 301 | $GLOBALS['_xh'][$parser]['st'].='"'. $GLOBALS['_xh'][$parser]['ac'] . '"'; |
---|
| 302 | } |
---|
| 303 | elseif ($GLOBALS['_xh'][$parser]['qt']==2) |
---|
| 304 | { |
---|
| 305 | $GLOBALS['_xh'][$parser]['st'].="base64_decode('". $GLOBALS['_xh'][$parser]['ac'] . "')"; |
---|
| 306 | } |
---|
| 307 | elseif ($name=='BOOLEAN') |
---|
| 308 | { |
---|
| 309 | $GLOBALS['_xh'][$parser]['st'].=$GLOBALS['_xh'][$parser]['ac']; |
---|
| 310 | } |
---|
| 311 | else |
---|
| 312 | { |
---|
| 313 | // we have an I4, INT or a DOUBLE |
---|
| 314 | // we must check that only 0123456789-.<space> are characters here |
---|
[5912] | 315 | if (!preg_match('/^\-?[0123456789 \t\.]+$/', $GLOBALS['_xh'][$parser]['ac'])) |
---|
[2] | 316 | { |
---|
| 317 | // TODO: find a better way of throwing an error |
---|
| 318 | // than this! |
---|
| 319 | error_log('XML-RPC: non numeric value received in INT or DOUBLE'); |
---|
| 320 | $GLOBALS['_xh'][$parser]['st'].='ERROR_NON_NUMERIC_FOUND'; |
---|
| 321 | } |
---|
| 322 | else |
---|
| 323 | { |
---|
| 324 | // it's ok, add it on |
---|
| 325 | $GLOBALS['_xh'][$parser]['st'].=$GLOBALS['_xh'][$parser]['ac']; |
---|
| 326 | } |
---|
| 327 | } |
---|
| 328 | $GLOBALS['_xh'][$parser]['ac']=""; $GLOBALS['_xh'][$parser]['qt']=0; |
---|
| 329 | $GLOBALS['_xh'][$parser]['lv']=3; // indicate we've found a value |
---|
| 330 | break; |
---|
| 331 | case 'VALUE': |
---|
| 332 | // deal with a string value |
---|
| 333 | if (strlen($GLOBALS['_xh'][$parser]['ac'])>0 && |
---|
| 334 | $GLOBALS['_xh'][$parser]['vt']==xmlrpcString) |
---|
| 335 | { |
---|
| 336 | $GLOBALS['_xh'][$parser]['st'].='"'. $GLOBALS['_xh'][$parser]['ac'] . '"'; |
---|
| 337 | } |
---|
| 338 | // This if() detects if no scalar was inside <VALUE></VALUE> |
---|
| 339 | // and pads an empty "". |
---|
| 340 | if($GLOBALS['_xh'][$parser]['st'][strlen($GLOBALS['_xh'][$parser]['st'])-1] == '(') |
---|
| 341 | { |
---|
| 342 | $GLOBALS['_xh'][$parser]['st'].= '""'; |
---|
| 343 | } |
---|
| 344 | $GLOBALS['_xh'][$parser]['st'].=", '" . $GLOBALS['_xh'][$parser]['vt'] . "')"; |
---|
| 345 | if ($GLOBALS['_xh'][$parser]['cm']) |
---|
| 346 | { |
---|
| 347 | $GLOBALS['_xh'][$parser]['st'].=","; |
---|
| 348 | } |
---|
| 349 | break; |
---|
| 350 | case 'MEMBER': |
---|
| 351 | $GLOBALS['_xh'][$parser]['ac']=""; |
---|
| 352 | $GLOBALS['_xh'][$parser]['qt']=0; |
---|
| 353 | break; |
---|
| 354 | case 'DATA': |
---|
| 355 | $GLOBALS['_xh'][$parser]['ac']=""; |
---|
| 356 | $GLOBALS['_xh'][$parser]['qt']=0; |
---|
| 357 | break; |
---|
| 358 | case 'PARAM': |
---|
| 359 | $GLOBALS['_xh'][$parser]['params'][]=$GLOBALS['_xh'][$parser]['st']; |
---|
| 360 | break; |
---|
| 361 | case 'METHODNAME': |
---|
[5934] | 362 | $GLOBALS['_xh'][$parser]['method']=preg_replace('/^[\n\r\t ]+/', '', $GLOBALS['_xh'][$parser]['ac']); |
---|
[2] | 363 | break; |
---|
| 364 | case 'BOOLEAN': |
---|
| 365 | // special case here: we translate boolean 1 or 0 into PHP |
---|
| 366 | // constants true or false |
---|
| 367 | if ($GLOBALS['_xh'][$parser]['ac']=='1') |
---|
| 368 | { |
---|
| 369 | $GLOBALS['_xh'][$parser]['ac']='True'; |
---|
| 370 | } |
---|
| 371 | else |
---|
| 372 | { |
---|
| 373 | $GLOBALS['_xh'][$parser]['ac']='false'; |
---|
| 374 | } |
---|
| 375 | $GLOBALS['_xh'][$parser]['vt']=strtolower($name); |
---|
| 376 | break; |
---|
| 377 | default: |
---|
| 378 | break; |
---|
| 379 | } |
---|
| 380 | // if it's a valid type name, set the type |
---|
| 381 | if (isset($GLOBALS['xmlrpcTypes'][strtolower($name)])) |
---|
| 382 | { |
---|
| 383 | $GLOBALS['_xh'][$parser]['vt']=strtolower($name); |
---|
| 384 | } |
---|
| 385 | } |
---|
| 386 | |
---|
| 387 | function xmlrpc_cd($parser, $data) |
---|
| 388 | { |
---|
[5912] | 389 | //if (preg_match('/^[\n\r \t]+$/', $data)) return; |
---|
[2] | 390 | // print "adding [${data}]\n"; |
---|
| 391 | |
---|
| 392 | if ($GLOBALS['_xh'][$parser]['lv']!=3) |
---|
| 393 | { |
---|
| 394 | // "lookforvalue==3" means that we've found an entire value |
---|
| 395 | // and should discard any further character data |
---|
| 396 | if ($GLOBALS['_xh'][$parser]['lv']==1) |
---|
| 397 | { |
---|
| 398 | // if we've found text and we're just in a <value> then |
---|
| 399 | // turn quoting on, as this will be a string |
---|
| 400 | $GLOBALS['_xh'][$parser]['qt']=1; |
---|
| 401 | // and say we've found a value |
---|
| 402 | $GLOBALS['_xh'][$parser]['lv']=2; |
---|
| 403 | } |
---|
| 404 | $GLOBALS['_xh'][$parser]['ac'].=str_replace('$', '\$', |
---|
| 405 | str_replace('"', '\"', |
---|
| 406 | str_replace(chr(92),$GLOBALS['xmlrpc_backslash'], $data))); |
---|
| 407 | } |
---|
| 408 | } |
---|
| 409 | |
---|
| 410 | function xmlrpc_dh($parser, $data) |
---|
| 411 | { |
---|
| 412 | if (substr($data, 0, 1) == '&' && substr($data, -1, 1) == ';') |
---|
| 413 | { |
---|
| 414 | if ($GLOBALS['_xh'][$parser]['lv']==1) |
---|
| 415 | { |
---|
| 416 | $GLOBALS['_xh'][$parser]['qt']=1; |
---|
| 417 | $GLOBALS['_xh'][$parser]['lv']=2; |
---|
| 418 | } |
---|
| 419 | $GLOBALS['_xh'][$parser]['ac'].=str_replace('$', '\$', |
---|
| 420 | str_replace('"', '\"', |
---|
| 421 | str_replace(chr(92),$GLOBALS['xmlrpc_backslash'], $data))); |
---|
| 422 | } |
---|
| 423 | } |
---|
| 424 | |
---|
| 425 | // date helpers |
---|
| 426 | function iso8601_encode($timet, $utc=0) |
---|
| 427 | { |
---|
| 428 | // return an ISO8601 encoded string |
---|
| 429 | // really, timezones ought to be supported |
---|
| 430 | // but the XML-RPC spec says: |
---|
| 431 | // |
---|
| 432 | // "Don't assume a timezone. It should be specified by the server in its |
---|
| 433 | // documentation what assumptions it makes about timezones." |
---|
| 434 | // |
---|
| 435 | // these routines always assume localtime unless |
---|
| 436 | // $utc is set to 1, in which case UTC is assumed |
---|
| 437 | // and an adjustment for locale is made when encoding |
---|
| 438 | if (!$utc) |
---|
| 439 | { |
---|
| 440 | $t=strftime("%Y%m%dT%H:%M:%S", $timet); |
---|
| 441 | } |
---|
| 442 | else |
---|
| 443 | { |
---|
| 444 | if (function_exists("gmstrftime")) |
---|
| 445 | { |
---|
| 446 | // gmstrftime doesn't exist in some versions |
---|
| 447 | // of PHP |
---|
| 448 | $t=gmstrftime("%Y%m%dT%H:%M:%S", $timet); |
---|
| 449 | } |
---|
| 450 | else |
---|
| 451 | { |
---|
| 452 | $t=strftime("%Y%m%dT%H:%M:%S", $timet-date("Z")); |
---|
| 453 | } |
---|
| 454 | } |
---|
| 455 | return $t; |
---|
| 456 | } |
---|
| 457 | |
---|
| 458 | function iso8601_decode($idate, $utc=0) |
---|
| 459 | { |
---|
| 460 | // return a timet in the localtime, or UTC |
---|
| 461 | $t=0; |
---|
[5912] | 462 | if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/',$idate, $regs)) |
---|
[2] | 463 | { |
---|
| 464 | if ($utc) |
---|
| 465 | { |
---|
| 466 | $t=gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); |
---|
| 467 | } |
---|
| 468 | else |
---|
| 469 | { |
---|
| 470 | $t=mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); |
---|
| 471 | } |
---|
| 472 | } |
---|
| 473 | return $t; |
---|
| 474 | } |
---|
| 475 | |
---|
| 476 | /**************************************************************** |
---|
| 477 | * xmlrpc_decode takes a message in PHP xmlrpc object format and * |
---|
| 478 | * tranlates it into native PHP types. * |
---|
| 479 | * * |
---|
| 480 | * author: Dan Libby (dan@libby.com) * |
---|
| 481 | ****************************************************************/ |
---|
| 482 | function phpgw_xmlrpc_decode($xmlrpc_val) |
---|
| 483 | { |
---|
| 484 | $kind = @$xmlrpc_val->kindOf(); |
---|
| 485 | |
---|
| 486 | if($kind == "scalar") |
---|
| 487 | { |
---|
| 488 | return $xmlrpc_val->scalarval(); |
---|
| 489 | } |
---|
| 490 | elseif($kind == "array") |
---|
| 491 | { |
---|
| 492 | $size = $xmlrpc_val->arraysize(); |
---|
| 493 | $arr = array(); |
---|
| 494 | |
---|
[7655] | 495 | for($i = 0; $i < $size; ++$i) |
---|
[2] | 496 | { |
---|
| 497 | $arr[]=phpgw_xmlrpc_decode($xmlrpc_val->arraymem($i)); |
---|
| 498 | } |
---|
| 499 | return $arr; |
---|
| 500 | } |
---|
| 501 | elseif($kind == "struct") |
---|
| 502 | { |
---|
| 503 | $xmlrpc_val->structreset(); |
---|
| 504 | $arr = array(); |
---|
| 505 | |
---|
| 506 | while(list($key,$value)=$xmlrpc_val->structeach()) |
---|
| 507 | { |
---|
| 508 | $arr[$key] = phpgw_xmlrpc_decode($value); |
---|
| 509 | } |
---|
| 510 | return $arr; |
---|
| 511 | } |
---|
| 512 | } |
---|
| 513 | |
---|
| 514 | /**************************************************************** |
---|
| 515 | * xmlrpc_encode takes native php types and encodes them into * |
---|
| 516 | * xmlrpc PHP object format. * |
---|
| 517 | * BUG: All sequential arrays are turned into structs. I don't * |
---|
| 518 | * know of a good way to determine if an array is sequential * |
---|
| 519 | * only. * |
---|
| 520 | * * |
---|
| 521 | * feature creep -- could support more types via optional type * |
---|
| 522 | * argument. * |
---|
| 523 | * * |
---|
| 524 | * author: Dan Libby (dan@libby.com) * |
---|
| 525 | ****************************************************************/ |
---|
| 526 | function phpgw_xmlrpc_encode($php_val) |
---|
| 527 | { |
---|
| 528 | $type = gettype($php_val); |
---|
| 529 | $xmlrpc_val = CreateObject('phpgwapi.xmlrpcval'); |
---|
| 530 | |
---|
| 531 | switch($type) |
---|
| 532 | { |
---|
| 533 | case "array": |
---|
| 534 | case "object": |
---|
| 535 | $arr = array(); |
---|
| 536 | while (list($k,$v) = each($php_val)) |
---|
| 537 | { |
---|
| 538 | $arr[$k] = phpgw_xmlrpc_encode($v); |
---|
| 539 | } |
---|
| 540 | $xmlrpc_val->addStruct($arr); |
---|
| 541 | break; |
---|
| 542 | case "integer": |
---|
| 543 | $xmlrpc_val->addScalar($php_val, xmlrpcInt); |
---|
| 544 | break; |
---|
| 545 | case "double": |
---|
| 546 | $xmlrpc_val->addScalar($php_val, xmlrpcDouble); |
---|
| 547 | break; |
---|
| 548 | case "string": |
---|
| 549 | $xmlrpc_val->addScalar($php_val, xmlrpcString); |
---|
| 550 | break; |
---|
| 551 | // <G_Giunta_2001-02-29> |
---|
| 552 | // Add support for encoding/decoding of booleans, since they are supported in PHP |
---|
| 553 | case "boolean": |
---|
| 554 | $xmlrpc_val->addScalar($php_val, xmlrpcBoolean); |
---|
| 555 | break; |
---|
| 556 | // </G_Giunta_2001-02-29> |
---|
| 557 | case "unknown type": |
---|
| 558 | default: |
---|
| 559 | $xmlrpc_val = false; |
---|
| 560 | break; |
---|
| 561 | } |
---|
| 562 | return $xmlrpc_val; |
---|
| 563 | } |
---|
| 564 | |
---|
| 565 | // listMethods: either a string, or nothing |
---|
| 566 | $GLOBALS['_xmlrpcs_listMethods_sig'] = array(array(xmlrpcArray, xmlrpcString), array(xmlrpcArray)); |
---|
| 567 | $GLOBALS['_xmlrpcs_listMethods_doc'] = 'This method lists all the methods that the XML-RPC server knows how to dispatch'; |
---|
| 568 | function _xmlrpcs_listMethods($server, $m) |
---|
| 569 | { |
---|
| 570 | $v = CreateObject('phpgwapi.xmlrpcval'); |
---|
| 571 | $dmap = $server->dmap; |
---|
| 572 | $outAr = array(); |
---|
| 573 | for(reset($dmap); list($key, $val) = each($dmap); ) |
---|
| 574 | { |
---|
| 575 | $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string'); |
---|
| 576 | } |
---|
| 577 | $dmap = $GLOBALS['_xmlrpcs_dmap']; |
---|
| 578 | for(reset($dmap); list($key, $val) = each($dmap); ) |
---|
| 579 | { |
---|
| 580 | $outAr[] = CreateObject('phpgwapi.xmlrpcval',$key, 'string'); |
---|
| 581 | } |
---|
| 582 | $v->addArray($outAr); |
---|
| 583 | return CreateObject('phpgwapi.xmlrpcresp',$v); |
---|
| 584 | } |
---|
| 585 | |
---|
| 586 | $GLOBALS['_xmlrpcs_methodSignature_sig']=array(array(xmlrpcArray, xmlrpcString)); |
---|
| 587 | $GLOBALS['_xmlrpcs_methodSignature_doc']='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)'; |
---|
| 588 | function _xmlrpcs_methodSignature($server, $m) |
---|
| 589 | { |
---|
| 590 | $methName = $m->getParam(0); |
---|
| 591 | $methName = $methName->scalarval(); |
---|
[5912] | 592 | if (preg_match('/^system\./', $methName)) |
---|
[2] | 593 | { |
---|
| 594 | $dmap = $GLOBALS['_xmlrpcs_dmap']; |
---|
| 595 | $sysCall = 1; |
---|
| 596 | } |
---|
| 597 | else |
---|
| 598 | { |
---|
| 599 | $dmap = $server->dmap; |
---|
| 600 | $sysCall = 0; |
---|
| 601 | } |
---|
| 602 | // print "<!-- ${methName} -->\n"; |
---|
| 603 | if (isset($dmap[$methName])) |
---|
| 604 | { |
---|
| 605 | if ($dmap[$methName]['signature']) |
---|
| 606 | { |
---|
| 607 | $sigs = array(); |
---|
| 608 | $thesigs=$dmap[$methName]['signature']; |
---|
[7655] | 609 | for($i=0; $i<sizeof($thesigs); ++$i) |
---|
[2] | 610 | { |
---|
| 611 | $cursig = array(); |
---|
| 612 | $inSig = $thesigs[$i]; |
---|
[7655] | 613 | for($j=0; $j<sizeof($inSig); ++$j) |
---|
[2] | 614 | { |
---|
| 615 | $cursig[] = CreateObject('phpgwapi.xmlrpcval',$inSig[$j], 'string'); |
---|
| 616 | } |
---|
| 617 | $sigs[] = CreateObject('phpgwapi.xmlrpcval',$cursig, 'array'); |
---|
| 618 | } |
---|
| 619 | $r = CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$sigs, 'array')); |
---|
| 620 | } |
---|
| 621 | else |
---|
| 622 | { |
---|
| 623 | $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval','undef', 'string')); |
---|
| 624 | } |
---|
| 625 | } |
---|
| 626 | else |
---|
| 627 | { |
---|
| 628 | $r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']); |
---|
| 629 | } |
---|
| 630 | return $r; |
---|
| 631 | } |
---|
| 632 | |
---|
| 633 | $GLOBALS['_xmlrpcs_methodHelp_sig'] = array(array(xmlrpcString, xmlrpcString)); |
---|
| 634 | $GLOBALS['_xmlrpcs_methodHelp_doc'] = 'Returns help text if defined for the method passed, otherwise returns an empty string'; |
---|
| 635 | function _xmlrpcs_methodHelp($server, $m) |
---|
| 636 | { |
---|
| 637 | $methName = $m->getParam(0); |
---|
| 638 | $methName = $methName->scalarval(); |
---|
[5912] | 639 | if (preg_match('/^system\./', $methName)) |
---|
[2] | 640 | { |
---|
| 641 | $dmap = $GLOBALS['_xmlrpcs_dmap']; |
---|
| 642 | $sysCall=1; |
---|
| 643 | } |
---|
| 644 | else |
---|
| 645 | { |
---|
| 646 | $dmap = $server->dmap; |
---|
| 647 | $sysCall=0; |
---|
| 648 | } |
---|
| 649 | // print "<!-- ${methName} -->\n"; |
---|
| 650 | if (isset($dmap[$methName])) |
---|
| 651 | { |
---|
| 652 | if ($dmap[$methName]['docstring']) |
---|
| 653 | { |
---|
| 654 | $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval',$dmap[$methName]['docstring']),'string'); |
---|
| 655 | } |
---|
| 656 | else |
---|
| 657 | { |
---|
| 658 | $r = CreateObject('phpgwapi.xmlrpcresp', CreateObject('phpgwapi.xmlrpcval'), 'string'); |
---|
| 659 | } |
---|
| 660 | } |
---|
| 661 | else |
---|
| 662 | { |
---|
| 663 | $r = CreateObject('phpgwapi.xmlrpcresp',0,$GLOBALS['xmlrpcerr']['introspect_unknown'],$GLOBALS['xmlrpcstr']['introspect_unknown']); |
---|
| 664 | } |
---|
| 665 | return $r; |
---|
| 666 | } |
---|
| 667 | |
---|
| 668 | /* |
---|
| 669 | $GLOBALS['_xmlrpcs_listApps_sig'] = array(array(xmlrpcStruct,xmlrpcString)); |
---|
| 670 | $GLOBALS['_xmlrpcs_listApps_doc'] = 'Returns a list of installed phpgw apps'; |
---|
| 671 | function _xmlrpcs_listApps($server,$m) |
---|
| 672 | { |
---|
| 673 | $m->getParam(0); |
---|
| 674 | $GLOBALS['phpgw']->db->query("SELECT * FROM phpgw_applications WHERE app_enabled<3",__LINE__,__FILE__); |
---|
| 675 | if($GLOBALS['phpgw']->db->num_rows()) |
---|
| 676 | { |
---|
| 677 | while ($GLOBALS['phpgw']->db->next_record()) |
---|
| 678 | { |
---|
| 679 | $name = $GLOBALS['phpgw']->db->f('app_name'); |
---|
| 680 | $title = $GLOBALS['phpgw']->db->f('app_title'); |
---|
| 681 | $status = $GLOBALS['phpgw']->db->f('app_enabled'); |
---|
| 682 | $version= $GLOBALS['phpgw']->db->f('app_version'); |
---|
| 683 | $apps[$name] = CreateObject('phpgwapi.xmlrpcval', |
---|
| 684 | array( |
---|
| 685 | 'title' => CreateObject('phpgwapi.xmlrpcval',$title,'string'), |
---|
| 686 | 'name' => CreateObject('phpgwapi.xmlrpcval',$name,'string'), |
---|
| 687 | 'status' => CreateObject('phpgwapi.xmlrpcval',$status,'string'), |
---|
| 688 | 'version'=> CreateObject('phpgwapi.xmlrpcval',$version,'string') |
---|
| 689 | ), |
---|
| 690 | 'struct' |
---|
| 691 | ); |
---|
| 692 | } |
---|
| 693 | } |
---|
| 694 | return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$apps, 'struct')); |
---|
| 695 | } |
---|
| 696 | */ |
---|
| 697 | |
---|
| 698 | $GLOBALS['_xmlrpcs_login_sig'] = array(array(xmlrpcStruct,xmlrpcStruct)); |
---|
| 699 | $GLOBALS['_xmlrpcs_login_doc'] = 'phpGroupWare client or server login via XML-RPC'; |
---|
| 700 | function _xmlrpcs_login($server,$m) |
---|
| 701 | { |
---|
| 702 | $rdata = $m->getParam(0); |
---|
| 703 | $data = $rdata->scalarval(); |
---|
| 704 | |
---|
| 705 | if($data['server_name']) |
---|
| 706 | { |
---|
| 707 | $server_name = $data['server_name']->scalarval(); |
---|
| 708 | } |
---|
| 709 | if($data['domain']) |
---|
| 710 | { |
---|
| 711 | $domain = $data['domain']->scalarval(); |
---|
| 712 | } |
---|
| 713 | $username = $data['username']->scalarval(); |
---|
| 714 | $password = $data['password']->scalarval(); |
---|
| 715 | |
---|
| 716 | if($server_name) |
---|
| 717 | { |
---|
| 718 | list($sessionid,$kp3) = $GLOBALS['phpgw']->session->create_server($username.'@'.$server_name,$password,"text"); |
---|
| 719 | } |
---|
| 720 | else |
---|
| 721 | { |
---|
| 722 | if($domain) |
---|
| 723 | { |
---|
| 724 | $user = $username.'@'.$domain; |
---|
| 725 | } |
---|
| 726 | else |
---|
| 727 | { |
---|
| 728 | $user = $username; |
---|
| 729 | } |
---|
| 730 | $sessionid = $GLOBALS['phpgw']->session->create($user,$password,"text"); |
---|
| 731 | $kp3 = $GLOBALS['phpgw']->session->kp3; |
---|
| 732 | $domain = $GLOBALS['phpgw']->session->account_domain; |
---|
| 733 | } |
---|
| 734 | |
---|
| 735 | if($sessionid && $kp3) |
---|
| 736 | { |
---|
| 737 | $rtrn['domain'] = CreateObject('phpgwapi.xmlrpcval',$domain,'string'); |
---|
| 738 | $rtrn['sessionid'] = CreateObject('phpgwapi.xmlrpcval',$sessionid,'string'); |
---|
| 739 | $rtrn['kp3'] = CreateObject('phpgwapi.xmlrpcval',$kp3,'string'); |
---|
| 740 | } |
---|
| 741 | else |
---|
| 742 | { |
---|
| 743 | $rtrn['GOAWAY'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string'); |
---|
| 744 | } |
---|
| 745 | return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct')); |
---|
| 746 | } |
---|
| 747 | |
---|
| 748 | $GLOBALS['_xmlrpcs_phpgw_api_version_sig'] = array(array(xmlrpcString,xmlrpcString)); |
---|
| 749 | $GLOBALS['_xmlrpcs_phpgw_api_version_doc'] = 'Returns the phpGroupWare API version'; |
---|
| 750 | function _xmlrpcs_phpgw_api_version($server,$m) |
---|
| 751 | { |
---|
| 752 | $version = $GLOBALS['phpgw_info']['server']['versions']['phpgwapi']; |
---|
| 753 | |
---|
| 754 | return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$version,'string')); |
---|
| 755 | } |
---|
| 756 | |
---|
| 757 | |
---|
| 758 | $GLOBALS['_xmlrpcs_logout_sig'] = array(array(xmlrpcStruct,xmlrpcStruct)); |
---|
| 759 | $GLOBALS['_xmlrpcs_logout_doc'] = 'phpGroupWare client or server logout via XML-RPC'; |
---|
| 760 | function _xmlrpcs_logout($server,$m) |
---|
| 761 | { |
---|
| 762 | $rdata = $m->getParam(0); |
---|
| 763 | $data = $rdata->scalarval(); |
---|
| 764 | |
---|
| 765 | $sessionid = $data['sessionid']->scalarval(); |
---|
| 766 | $kp3 = $data['kp3']->scalarval(); |
---|
| 767 | |
---|
| 768 | $later = $GLOBALS['phpgw']->session->destroy($sessionid,$kp3); |
---|
| 769 | |
---|
| 770 | if ($later) |
---|
| 771 | { |
---|
| 772 | $rtrn['GOODBYE'] = CreateObject('phpgwapi.xmlrpcval','XOXO','string'); |
---|
| 773 | } |
---|
| 774 | else |
---|
| 775 | { |
---|
| 776 | /* This never happens, yet */ |
---|
| 777 | $rtrn['OOPS'] = CreateObject('phpgwapi.xmlrpcval','WHAT?','string'); |
---|
| 778 | } |
---|
| 779 | return CreateObject('phpgwapi.xmlrpcresp',CreateObject('phpgwapi.xmlrpcval',$rtrn,'struct')); |
---|
| 780 | } |
---|
| 781 | |
---|
| 782 | $GLOBALS['_xmlrpcs_dmap'] = array( |
---|
| 783 | 'system.listMethods' => array( |
---|
| 784 | 'function' => '_xmlrpcs_listMethods', |
---|
| 785 | 'signature' => $GLOBALS['_xmlrpcs_listMethods_sig'], |
---|
| 786 | 'docstring' => $GLOBALS['_xmlrpcs_listMethods_doc'] |
---|
| 787 | ), |
---|
| 788 | 'system.methodHelp' => array( |
---|
| 789 | 'function' => '_xmlrpcs_methodHelp', |
---|
| 790 | 'signature' => $GLOBALS['_xmlrpcs_methodHelp_sig'], |
---|
| 791 | 'docstring' => $GLOBALS['_xmlrpcs_methodHelp_doc'] |
---|
| 792 | ), |
---|
| 793 | 'system.methodSignature' => array( |
---|
| 794 | 'function' => '_xmlrpcs_methodSignature', |
---|
| 795 | 'signature' => $GLOBALS['_xmlrpcs_methodSignature_sig'], |
---|
| 796 | 'docstring' => $GLOBALS['_xmlrpcs_methodSignature_doc'] |
---|
| 797 | ), |
---|
| 798 | /* |
---|
| 799 | 'system.listApps' => array( |
---|
| 800 | 'function' => '_xmlrpcs_listApps', |
---|
| 801 | 'signature' => $GLOBALS['_xmlrpcs_listApps_sig'], |
---|
| 802 | 'docstring' => $GLOBALS['_xmlrpcs_listApps_doc'] |
---|
| 803 | ), |
---|
| 804 | */ |
---|
| 805 | 'system.login' => array( |
---|
| 806 | 'function' => '_xmlrpcs_login', |
---|
| 807 | 'signature' => $GLOBALS['_xmlrpcs_login_sig'], |
---|
| 808 | 'docstring' => $GLOBALS['_xmlrpcs_login_doc'] |
---|
| 809 | ), |
---|
| 810 | 'system.logout' => array( |
---|
| 811 | 'function' => '_xmlrpcs_logout', |
---|
| 812 | 'signature' => $GLOBALS['_xmlrpcs_logout_sig'], |
---|
| 813 | 'docstring' => $GLOBALS['_xmlrpcs_logout_doc'] |
---|
| 814 | ), |
---|
| 815 | 'system.phpgw_api_version' => array( |
---|
| 816 | 'function' => '_xmlrpcs_phpgw_api_version', |
---|
| 817 | 'signature' => $GLOBALS['_xmlrpcs_phpgw_api_version_sig'], |
---|
| 818 | 'docstring' => $GLOBALS['_xmlrpcs_phpgw_api_version_doc'] |
---|
| 819 | ) |
---|
| 820 | ); |
---|
| 821 | |
---|
| 822 | $GLOBALS['_xmlrpc_debuginfo'] = ''; |
---|
| 823 | function xmlrpc_debugmsg($m) |
---|
| 824 | { |
---|
| 825 | $GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n"; |
---|
| 826 | } |
---|
| 827 | ?> |
---|