├── CREDITS ├── Makefile.frag ├── EXPERIMENTAL ├── tests ├── bug77242.phpt ├── bug70526.phpt ├── bug42189.phpt ├── 004.phpt ├── bug77380.phpt ├── bug51288.phpt ├── bug61097.phpt ├── bug61264.phpt ├── 007.phpt ├── 006.phpt ├── bug18916.phpt ├── bug71501.phpt ├── bug72155.phpt ├── bug38431.phpt ├── bug72647.phpt ├── bug70728.phpt ├── bug70728_64bit.phpt ├── bug45555.phpt ├── bug50282.phpt ├── 005.phpt ├── 002.phpt ├── bug74975.phpt ├── bug47818.phpt ├── 001.phpt ├── bug45556.phpt ├── bug68027.phpt ├── bug45226.phpt ├── bug37057.phpt ├── bug44996.phpt ├── bug42736.phpt ├── bug40576_64bit.phpt ├── bug40576.phpt ├── bug50761.phpt ├── 003.phpt └── bug50285.phpt ├── libxmlrpc ├── README.md ├── base64.h ├── COPYING ├── xml_to_soap.h ├── xml_to_xmlrpc.h ├── xml_to_dandarpc.h ├── encodings.h ├── simplestring.h ├── queue.h ├── system_methods_private.h ├── xmlrpc_introspection.h ├── encodings.c ├── xmlrpc_introspection_private.h ├── base64.c ├── xmlrpc_private.h ├── xml_element.h ├── simplestring.c ├── xml_to_dandarpc.c ├── system_methods.c ├── xml_to_xmlrpc.c ├── xmlrpc.h └── xmlrpc_introspection.c ├── config.w32 ├── .gitignore ├── .github └── workflows │ └── ci.yml ├── xmlrpc.stub.php ├── php_xmlrpc.h ├── LICENSE ├── config.m4 ├── xmlrpc_arginfo.h └── package.xml /CREDITS: -------------------------------------------------------------------------------- 1 | xmlrpc 2 | Dan Libby 3 | -------------------------------------------------------------------------------- /Makefile.frag: -------------------------------------------------------------------------------- 1 | $(builddir)/xmlrpc-epi-php.lo: $(top_srcdir)/xmlrpc_arginfo.h 2 | @touch $@ 3 | 4 | -------------------------------------------------------------------------------- /EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | this extension is experimental, 2 | its functions may change their names 3 | or move to extension all together 4 | so do not rely to much on them 5 | you have been warned! 6 | -------------------------------------------------------------------------------- /tests/bug77242.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #77242 (heap out of bounds read in xmlrpc_decode()) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 9 | --EXPECT-- 10 | NULL -------------------------------------------------------------------------------- /tests/bug70526.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #70526 (xmlrpc_set_type returns false on success) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | bool(true) 15 | -------------------------------------------------------------------------------- /tests/bug42189.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #42189 (xmlrpc_get_type() crashes PHP on invalid dates) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 13 | --EXPECT-- 14 | bool(false) 15 | Done 16 | -------------------------------------------------------------------------------- /tests/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_encode() Simple test encode int 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | 13 | 14 | 15 | 1 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/bug77380.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #77380 (Global out of bounds read in xmlrpc base64 code) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 11 | --EXPECT-- 12 | object(stdClass)#1 (2) { 13 | ["scalar"]=> 14 | string(0) "" 15 | ["xmlrpc_type"]=> 16 | string(6) "base64" 17 | } 18 | -------------------------------------------------------------------------------- /tests/bug51288.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #51288 (CVE-2010-0397, NULL pointer deref when no in request) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | '; 9 | var_dump(xmlrpc_decode_request($req, $method)); 10 | var_dump($method); 11 | echo "Done\n"; 12 | ?> 13 | --EXPECT-- 14 | NULL 15 | NULL 16 | Done 17 | -------------------------------------------------------------------------------- /tests/bug61097.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #61097 (Memory leak in xmlrpc functions copying zvals) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 15 | --EXPECT-- 16 | Done 17 | -------------------------------------------------------------------------------- /tests/bug61264.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #61264: xmlrpc_parse_method_descriptions leaks temporary variable 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 9 | 10 | foo 11 | 12 | XML; 13 | var_dump(xmlrpc_parse_method_descriptions($xml)); 14 | ?> 15 | --EXPECT-- 16 | array(1) { 17 | ["b"]=> 18 | string(3) "foo" 19 | } 20 | -------------------------------------------------------------------------------- /tests/007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_decode() Simple test decode type int 3 | --CREDITS-- 4 | Michel Araujo 5 | #PHPSP 2013-08-22 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 13 | 14 | 15 | 16 | 1 17 | 18 | 19 | 20 | XML; 21 | 22 | $response = xmlrpc_decode($xml); 23 | echo $response; 24 | --EXPECT-- 25 | 1 26 | -------------------------------------------------------------------------------- /tests/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_decode() Simple test decode type string 3 | --CREDITS-- 4 | Michel Araujo 5 | #PHPSP 2013-08-22 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 13 | 14 | 15 | 16 | Is string 17 | 18 | 19 | 20 | XML; 21 | 22 | $response = xmlrpc_decode($xml); 23 | echo $response; 24 | --EXPECT-- 25 | Is string 26 | -------------------------------------------------------------------------------- /tests/bug18916.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #18916 (xmlrpc_set_type() not working) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | date.timezone="America/Sao_Paulo" 7 | --FILE-- 8 | 15 | --EXPECTF-- 16 | 17 | 18 | 19 | 20 | %dT%d:%d:%d 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/bug71501.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #71501 (xmlrpc_encode_request ignores encoding option) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 'UTF-8', 'escaping' => 'markup']); 11 | ?> 12 | --EXPECT-- 13 | 14 | 15 | foo 16 | 17 | 18 | 19 | Lê Trung Hiếu 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/bug72155.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #72155 (use-after-free caused by get_zval_xmlrpc_type) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 18 | --EXPECT-- 19 | string(109) " 20 | 21 | 22 | 23 | 5 24 | 25 | 26 | 27 | " 28 | -------------------------------------------------------------------------------- /tests/bug38431.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #38431 (xmlrpc_get_type() crashes PHP on objects) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 1,2,3); 13 | var_dump(xmlrpc_get_type($var)); 14 | $var = array("test"=>1,"test2"=>2); 15 | var_dump(xmlrpc_get_type($var)); 16 | 17 | echo "Done\n"; 18 | ?> 19 | --EXPECT-- 20 | string(5) "array" 21 | string(5) "array" 22 | string(5) "array" 23 | string(5) "mixed" 24 | string(6) "struct" 25 | Done 26 | -------------------------------------------------------------------------------- /tests/bug72647.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #72647 (xmlrpc_encode() unexpected output after referencing array elements) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 16 | --EXPECT-- 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 4 25 | 26 | 27 | a 28 | 29 | 30 | 7 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /libxmlrpc/README.md: -------------------------------------------------------------------------------- 1 | # libxmlrpc 2 | 3 | This is a fork of the [xmlrpc-epi library](http://xmlrpc-epi.sourceforge.net/) 4 | written by Dan Libby. 5 | 6 | ## Original coding conventions 7 | 8 | Organization of this directory is moving towards this approach: 9 | 10 | * `.h` -- public API and data types 11 | * `_private.h` -- protected API and data types 12 | * `.c` -- implementation and private API / types 13 | 14 | The rules are: 15 | 16 | * `.c` files may include `*_private.h`. 17 | * `.h` files may not include `*_private.h` 18 | 19 | This allows us to have a nicely encapsulated C api with opaque data types and 20 | private functions that are nonetheless shared between source files without 21 | redundant extern declarations.. 22 | -------------------------------------------------------------------------------- /tests/bug70728.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker) 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | xmlrpc_type = 'base64'; 12 | $obj->scalar = 0x1122334455; 13 | var_dump(xmlrpc_encode($obj)); 14 | var_dump($obj); 15 | ?> 16 | --EXPECT-- 17 | string(135) " 18 | 19 | 20 | 21 | NzM1ODgyMjkyMDU= 22 | 23 | 24 | 25 | " 26 | object(stdClass)#1 (2) { 27 | ["xmlrpc_type"]=> 28 | string(6) "base64" 29 | ["scalar"]=> 30 | float(73588229205) 31 | } 32 | -------------------------------------------------------------------------------- /tests/bug70728_64bit.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker) 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | xmlrpc_type = 'base64'; 12 | $obj->scalar = 0x1122334455; 13 | var_dump(xmlrpc_encode($obj)); 14 | var_dump($obj); 15 | ?> 16 | --EXPECT-- 17 | string(135) " 18 | 19 | 20 | 21 | NzM1ODgyMjkyMDU= 22 | 23 | 24 | 25 | " 26 | object(stdClass)#1 (2) { 27 | ["xmlrpc_type"]=> 28 | string(6) "base64" 29 | ["scalar"]=> 30 | int(73588229205) 31 | } 32 | -------------------------------------------------------------------------------- /tests/bug45555.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #45555 (Segfault with invalid non-string as register_introspection_callback) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 'xml', 'version' => 'xmlrpc'); 16 | xmlrpc_server_call_method ($server, $request, NULL, $options); 17 | 18 | ?> 19 | --EXPECTF-- 20 | Warning: xmlrpc_server_call_method(): Invalid callback '1' passed in %s on line %d 21 | 22 | Warning: xmlrpc_server_call_method(): Invalid callback 'foo::bar' passed in %s on line %d 23 | -------------------------------------------------------------------------------- /tests/bug50282.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #50282 (xmlrpc_encode_request() changes object into array in calling function) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 16 | --EXPECTF-- 17 | object(One)#%d (1) { 18 | ["x"]=> 19 | int(10) 20 | } 21 | string(279) " 22 | 23 | test 24 | 25 | 26 | 27 | 28 | 29 | x 30 | 31 | 10 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | " 40 | object(One)#%d (1) { 41 | ["x"]=> 42 | int(10) 43 | } 44 | -------------------------------------------------------------------------------- /libxmlrpc/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Encode or decode file as MIME base64 (RFC 1341) 4 | 5 | by John Walker 6 | http://www.fourmilab.ch/ 7 | 8 | This program is in the public domain. 9 | 10 | */ 11 | 12 | 13 | struct buffer_st { 14 | char *data; 15 | int length; 16 | char *ptr; 17 | int offset; 18 | }; 19 | 20 | void buffer_new(struct buffer_st *b); 21 | void buffer_add(struct buffer_st *b, char c); 22 | void buffer_delete(struct buffer_st *b); 23 | 24 | void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length); 25 | void base64_decode_xmlrpc(struct buffer_st *b, const char *source, int length); 26 | 27 | /* 28 | #define DEBUG_MALLOC 29 | */ 30 | 31 | #ifdef DEBUG_MALLOC 32 | void *_malloc_real(size_t s, char *file, int line); 33 | void _free_real(void *p, char *file, int line); 34 | 35 | #define malloc(s) _malloc_real(s,__FILE__,__LINE__) 36 | #define free(p) _free_real(p, __FILE__,__LINE__) 37 | #endif 38 | -------------------------------------------------------------------------------- /tests/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_encode() Simple test encode type double and String 3 | --CREDITS-- 4 | Michel Araujo 5 | #PHPSP 2013-08-22 6 | --SKIPIF-- 7 | 8 | --FILE-- 9 | 21 | 22 | 23 | 24 | 3.24234 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -3.24234 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Is string 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // vim:ft=javascript 2 | 3 | ARG_WITH("xmlrpc", "XMLRPC-EPI support", "no"); 4 | 5 | if (PHP_XMLRPC != "no") { 6 | if (CHECK_HEADER_ADD_INCLUDE("xmlrpc.h", "CFLAGS_XMLRPC", configure_module_dirname + "/libxmlrpc") 7 | && CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_XMLRPC") 8 | && CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_XMLRPC", PHP_PHP_BUILD + "\\include\\libxml2") 9 | && ADD_EXTENSION_DEP('xmlrpc', 'libxml') 10 | && ADD_EXTENSION_DEP('xmlrpc', 'xml')) { 11 | EXTENSION('xmlrpc', 'xmlrpc-epi-php.c', PHP_XMLRPC_SHARED, "-DVERSION=\"0.50\""); 12 | ADD_SOURCES(configure_module_dirname + "/libxmlrpc", "base64.c simplestring.c xml_to_dandarpc.c \ 13 | xmlrpc_introspection.c encodings.c system_methods.c xml_to_xmlrpc.c \ 14 | queue.c xml_element.c xmlrpc.c xml_to_soap.c", "xmlrpc"); 15 | AC_DEFINE("HAVE_XMLRPC_BUNDLED", 1); 16 | } else { 17 | WARNING("xmlrpc support can't be enabled, libraries or headers are missing") 18 | PHP_XMLRPC = "no"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_encode_request() and various arguments 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 26 | --EXPECTF-- 27 | array(0) { 28 | } 29 | string(6) "method" 30 | array(1) { 31 | [0]=> 32 | int(1) 33 | } 34 | string(6) "method" 35 | array(1) { 36 | [0]=> 37 | string(5) "param" 38 | } 39 | string(6) "method" 40 | array(1) { 41 | [0]=> 42 | string(0) "" 43 | } 44 | string(2) "-1" 45 | Done 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | .libs 3 | .php-version 4 | .rbenv-version 5 | acinclude.m4 6 | aclocal.m4 7 | autom4te.cache 8 | build 9 | config.guess 10 | config.h 11 | config.h.in 12 | config.log 13 | config.nice 14 | config.status 15 | config.sub 16 | configure 17 | configure.in 18 | configure.ac 19 | extras 20 | include 21 | install-sh 22 | libtool 23 | ltmain.sh 24 | ltmain.sh.backup 25 | Makefile 26 | Makefile.fragments 27 | Makefile.global 28 | Makefile.objects 29 | missing 30 | mkinstalldirs 31 | modules 32 | run-tests.php 33 | tmp-php.ini 34 | yaml.loT 35 | 36 | # General Ignores 37 | *~ 38 | .#* 39 | *. 40 | *.dep 41 | *.slo 42 | *.mk 43 | *.mem 44 | *.gcda 45 | *.gcno 46 | *.la 47 | *.lo 48 | *.o 49 | *.a 50 | *.ncb 51 | *.opt 52 | *.plg 53 | *swp 54 | *.patch 55 | *.tgz 56 | *.tar.gz 57 | *.tar.bz2 58 | .FBCIndex 59 | .FBCLockFolder 60 | core 61 | 62 | # Test specific Ignores 63 | tests/*.diff 64 | tests/*.exp 65 | tests/*.log 66 | tests/*.out 67 | tests/*.php 68 | tests/*.sh 69 | 70 | # coverage 71 | /coverage.info 72 | /reports 73 | -------------------------------------------------------------------------------- /tests/bug74975.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #74975 Different serialization for classes 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | xmlrpc_type = 'base64'; 24 | $foo->scalar = 'foobar'; 25 | 26 | $bar = new Bar(); 27 | $bar->xmlrpc_type = 'base64'; 28 | $bar->scalar = 'foobar'; 29 | 30 | echo xmlrpc_encode([ 31 | 'foo' => $foo, 32 | 'bar' => $bar 33 | ]); 34 | 35 | ?> 36 | --EXPECT-- 37 | 38 | 39 | 40 | 41 | 42 | 43 | foo 44 | 45 | Zm9vYmFy 46 | 47 | 48 | 49 | bar 50 | 51 | Zm9vYmFy 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/bug47818.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #47818 (Segfault due to bound callback param) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | method = $method_name; 14 | print "Inside impl(): {$this->method}\n"; 15 | return array_sum($params); 16 | } 17 | 18 | function __construct() { 19 | $this->s = xmlrpc_server_create(); 20 | xmlrpc_server_register_method($this->s, 'add', array($this, 'impl')); 21 | } 22 | 23 | function call($req) { 24 | return xmlrpc_server_call_method($this->s, $req, null); 25 | } 26 | 27 | function getMethod() {return $this->method;} 28 | 29 | } 30 | 31 | $x = new MyXmlRpc; 32 | $resp = $x->call(xmlrpc_encode_request('add', array(1, 2, 3))); 33 | 34 | $method = $x->getMethod(); 35 | 36 | print "Global scope: $method\n"; 37 | 38 | ?> 39 | --EXPECT-- 40 | Inside impl(): add 41 | Global scope: add 42 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_encode_request() with wrong arguments 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 14 | --EXPECTF-- 15 | string(174) " 16 | 17 | -1 18 | 19 | 20 | 21 | 1 22 | 23 | 24 | 25 | 26 | " 27 | string(160) " 28 | 29 | 30 | 31 | 32 | 33 | 1 34 | 35 | 36 | 37 | 38 | " 39 | string(175) " 40 | 41 | 3.4 42 | 43 | 44 | 45 | 1 46 | 47 | 48 | 49 | 50 | " 51 | Done 52 | -------------------------------------------------------------------------------- /libxmlrpc/COPYING: -------------------------------------------------------------------------------- 1 | 2 | Files: * 3 | Copyright: (C) 2000 Epinions, Inc. 4 | 5 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 6 | of charge, to (a) use, copy, distribute, modify, perform and display this 7 | software and associated documentation files (the "Software"), and (b) 8 | permit others to whom the Software is furnished to do so as well. 9 | 10 | 1) The above copyright notice and this permission notice shall be included 11 | without modification in all copies or substantial portions of the 12 | Software. 13 | 14 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 15 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 16 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 17 | PURPOSE OR NONINFRINGEMENT. 18 | 19 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 21 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 22 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 23 | DAMAGES. -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | on: [push, pull_request] 3 | jobs: 4 | windows: 5 | defaults: 6 | run: 7 | shell: cmd 8 | strategy: 9 | matrix: 10 | version: ['8.0', '8.1', '8.2', '8.3'] 11 | arch: [x64, x86] 12 | ts: [ts] 13 | runs-on: windows-2019 14 | steps: 15 | - name: Checkout xmlrpc 16 | uses: actions/checkout@v4 17 | - name: Setup PHP 18 | id: setup-php 19 | uses: php/setup-php-sdk@v0.8 20 | with: 21 | version: ${{matrix.version}} 22 | arch: ${{matrix.arch}} 23 | ts: ${{matrix.ts}} 24 | deps: libiconv, libxml2 25 | - name: Enable Developer Command Prompt 26 | uses: ilammy/msvc-dev-cmd@v1 27 | with: 28 | arch: ${{matrix.arch}} 29 | toolset: ${{steps.setup-php.outputs.toolset}} 30 | - name: phpize 31 | run: phpize 32 | - name: configure 33 | run: configure --with-xmlrpc --with-prefix=${{steps.setup-php.outputs.prefix}} 34 | - name: make 35 | run: nmake 36 | - name: test 37 | run: nmake test TESTS="--show-diff tests" 38 | -------------------------------------------------------------------------------- /tests/bug45556.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #45556 (Return value from callback isn't freed) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 'xml', 'version' => 'xmlrpc'); 26 | xmlrpc_server_call_method ($server, $request, NULL, $options); 27 | 28 | ?> 29 | --EXPECTF-- 30 | Warning: xmlrpc_server_call_method(): Invalid callback 'foobar' passed in %s on line %d 31 | 32 | Warning: xmlrpc_server_call_method(): XML parse error: [line 1, column 1, message: %s] Unable to add introspection data returned from bar::test() in %s on line %d 33 | 34 | Warning: xmlrpc_server_call_method(): Invalid callback 'foo::bar' passed in %s on line %d 35 | -------------------------------------------------------------------------------- /tests/bug68027.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #68027 (buffer overflow in mkgmtime() function) 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | $datetime"); 15 | print_r($obj); 16 | 17 | $datetime = "34770-0-08T21:46:40-0400"; 18 | $obj = xmlrpc_decode("$datetime"); 19 | print_r($obj); 20 | 21 | echo "Done\n"; 22 | ?> 23 | --EXPECTF-- 24 | object(stdClass)#1 (3) { 25 | ["scalar"]=> 26 | string(16) "6-01-01 20:00:00" 27 | ["xmlrpc_type"]=> 28 | string(8) "datetime" 29 | ["timestamp"]=> 30 | int(%d) 31 | } 32 | stdClass Object 33 | ( 34 | [scalar] => 2001-0-08T21:46:40-0400 35 | [xmlrpc_type] => datetime 36 | [timestamp] => %s 37 | ) 38 | stdClass Object 39 | ( 40 | [scalar] => 34770-0-08T21:46:40-0400 41 | [xmlrpc_type] => datetime 42 | [timestamp] => %d 43 | ) 44 | Done 45 | -------------------------------------------------------------------------------- /xmlrpc.stub.php: -------------------------------------------------------------------------------- 1 | 7 | --FILE-- 8 | $d)); 13 | 14 | $d = '2008-01-01 20:00:00'; 15 | xmlrpc_set_type($d, 'datetime'); 16 | echo xmlrpc_encode_request('method.call', array('date' => $d)); 17 | 18 | ?> 19 | --EXPECTF-- 20 | 21 | 22 | method.call 23 | 24 | 25 | 26 | 27 | 28 | date 29 | 30 | %d-%d-%dT%d:%d:%d%s%d 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | method.call 41 | 42 | 43 | 44 | 45 | 46 | date 47 | 48 | %d-%d-%d %d:%d:%d 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /tests/bug37057.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #37057 (xmlrpc_decode() may produce arrays with numeric string keys which are unaccessible) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 50 15 | 0.29 16 | 17 | 18 | 19 | 20 | 21 | '; 22 | 23 | $retval=xmlrpc_decode($response); 24 | var_dump($retval); 25 | var_dump($retval["50"]); 26 | var_dump($retval[50]); 27 | 28 | $response=' 29 | 30 | 31 | 32 | 33 | 34 | 35 | 0 36 | 0.29 37 | 38 | 39 | 40 | 41 | 42 | '; 43 | 44 | $retval=xmlrpc_decode($response); 45 | var_dump($retval); 46 | var_dump($retval["0"]); 47 | var_dump($retval[0]); 48 | 49 | echo "Done\n"; 50 | ?> 51 | --EXPECT-- 52 | array(1) { 53 | [50]=> 54 | string(4) "0.29" 55 | } 56 | string(4) "0.29" 57 | string(4) "0.29" 58 | array(1) { 59 | [0]=> 60 | string(4) "0.29" 61 | } 62 | string(4) "0.29" 63 | string(4) "0.29" 64 | Done 65 | -------------------------------------------------------------------------------- /tests/bug44996.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #44996 (xmlrpc_decode() ignores time zone on iso8601.datetime) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | $datetime"); 11 | print_r($obj); 12 | } 13 | 14 | DecodeDatetime("20010909T01:46:40Z"); 15 | DecodeDatetime("20010909T00:46:40-01"); 16 | DecodeDatetime("2001-09-09T08:46:40+07:00"); 17 | DecodeDatetime("2001-09-08T21:46:40-0400"); 18 | 19 | ?> 20 | --EXPECT-- 21 | ISO 8601 datetime 20010909T01:46:40Z 22 | stdClass Object 23 | ( 24 | [scalar] => 20010909T01:46:40Z 25 | [xmlrpc_type] => datetime 26 | [timestamp] => 1000000000 27 | ) 28 | 29 | ISO 8601 datetime 20010909T00:46:40-01 30 | stdClass Object 31 | ( 32 | [scalar] => 20010909T00:46:40-01 33 | [xmlrpc_type] => datetime 34 | [timestamp] => 1000000000 35 | ) 36 | 37 | ISO 8601 datetime 2001-09-09T08:46:40+07:00 38 | stdClass Object 39 | ( 40 | [scalar] => 2001-09-09T08:46:40+07:00 41 | [xmlrpc_type] => datetime 42 | [timestamp] => 1000000000 43 | ) 44 | 45 | ISO 8601 datetime 2001-09-08T21:46:40-0400 46 | stdClass Object 47 | ( 48 | [scalar] => 2001-09-08T21:46:40-0400 49 | [xmlrpc_type] => datetime 50 | [timestamp] => 1000000000 51 | ) 52 | -------------------------------------------------------------------------------- /tests/bug42736.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #42736 (xmlrpc_server_call_method() crashes) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | add($id); 11 | } 12 | } 13 | 14 | $xml = xmlrpc_server_create(); 15 | 16 | $Myrequest = 'GetProducts20060922T14:26:19'; 17 | 18 | class MyClass { 19 | function GetProducts($dummy, $time){ 20 | return array('faultString' => $time); 21 | } 22 | } 23 | $myclass = new MyClass(); 24 | xmlrpc_server_register_method($xml, 'GetProducts', array($myclass, 'GetProducts')); 25 | $response = xmlrpc_server_call_method($xml, $Myrequest, null); 26 | 27 | var_dump($response); 28 | 29 | echo "Done\n"; 30 | ?> 31 | --EXPECT-- 32 | string(402) " 33 | 34 | 35 | 36 | 37 | 38 | 39 | faultString 40 | 41 | 42 | 43 | 44 | 20060922T14:26:19 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | " 56 | Done 57 | -------------------------------------------------------------------------------- /tests/bug40576_64bit.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #40576 (double values are truncated to 6 decimal digits when encoding) 3 | --SKIPIF-- 4 | 8 | --INI-- 9 | precision=12 10 | --FILE-- 11 | 22 | --EXPECT-- 23 | string(125) " 24 | 25 | 26 | 27 | 1.123456789 28 | 29 | 30 | 31 | " 32 | string(119) " 33 | 34 | 35 | 36 | -1066555326 37 | 38 | 39 | 40 | " 41 | string(116) " 42 | 43 | 44 | 45 | 11234567 46 | 47 | 48 | 49 | " 50 | string(106) " 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | " 59 | string(118) " 60 | 61 | 62 | 63 | test 64 | 65 | 66 | 67 | " 68 | string(139) " 69 | 70 | 71 | 72 | 1.22222222222222222222222 73 | 74 | 75 | 76 | " 77 | Done 78 | -------------------------------------------------------------------------------- /tests/bug40576.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #40576 (double values are truncated to 6 decimal digits when encoding) 3 | --SKIPIF-- 4 | 8 | --INI-- 9 | precision=12 10 | --FILE-- 11 | 22 | --EXPECT-- 23 | string(125) " 24 | 25 | 26 | 27 | 1.123456789 28 | 29 | 30 | 31 | " 32 | string(130) " 33 | 34 | 35 | 36 | 1.1234567891E+13 37 | 38 | 39 | 40 | " 41 | string(116) " 42 | 43 | 44 | 45 | 11234567 46 | 47 | 48 | 49 | " 50 | string(106) " 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | " 59 | string(118) " 60 | 61 | 62 | 63 | test 64 | 65 | 66 | 67 | " 68 | string(139) " 69 | 70 | 71 | 72 | 1.22222222222222222222222 73 | 74 | 75 | 76 | " 77 | Done 78 | -------------------------------------------------------------------------------- /libxmlrpc/xml_to_soap.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | #ifndef XML_TO_SOAP_H 35 | #define XML_TO_SOAP_H 36 | 37 | #include "xmlrpc.h" 38 | 39 | XMLRPC_VALUE xml_element_to_SOAP_VALUE(xml_element* el); 40 | XMLRPC_VALUE xml_element_to_SOAP_REQUEST(XMLRPC_REQUEST request, xml_element* el); 41 | xml_element* SOAP_VALUE_to_xml_element(XMLRPC_VALUE node); 42 | xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request); 43 | 44 | #endif /* XML_TO_XMLRPC_H */ 45 | -------------------------------------------------------------------------------- /libxmlrpc/xml_to_xmlrpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | #ifndef XML_TO_XMLRPC_H 35 | #define XML_TO_XMLRPC_H 36 | 37 | #include "time.h" 38 | #include "xmlrpc.h" 39 | 40 | XMLRPC_VALUE xml_element_to_XMLRPC_VALUE(xml_element* el); 41 | XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST(XMLRPC_REQUEST request, xml_element* el); 42 | xml_element* XMLRPC_VALUE_to_xml_element(XMLRPC_VALUE node); 43 | xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request); 44 | 45 | #endif /* XML_TO_XMLRPC_H */ 46 | -------------------------------------------------------------------------------- /libxmlrpc/xml_to_dandarpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #ifndef XML_TO_DANDARPC_H 34 | #define XML_TO_DANDARPC_H 35 | 36 | #include "time.h" 37 | #include "xmlrpc.h" 38 | 39 | XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el); 40 | XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el); 41 | xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node); 42 | xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request); 43 | 44 | #endif /* XML_TO_DANDARPC_H */ 45 | -------------------------------------------------------------------------------- /tests/bug50761.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #50761 (system.multiCall crashes) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 8 | 9 | system.multiCall 10 | 11 | 12 | methodNametestMethodA 13 | paramsA 14 | 15 | 16 | 17 | methodNametestMethodB 18 | paramsB 19 | 20 | 21 | 22 | '; 23 | 24 | function testA($methodName, $params, $var){ return "C"; } 25 | function testB($methodName, $params, $var){ return "D"; } 26 | 27 | $server = xmlrpc_server_create(); 28 | xmlrpc_server_register_method($server, 'testMethodA', 'testA'); 29 | xmlrpc_server_register_method($server, 'testMethodB', 'testB'); 30 | $res = xmlrpc_server_call_method($server, $req, null); 31 | echo $res; 32 | ?> 33 | --EXPECT-- 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | C 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | D 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /libxmlrpc/encodings.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | #ifndef __ENCODINGS__H 35 | #define __ENCODINGS__H 36 | 37 | /* these defines are for legacy purposes. */ 38 | #define encoding_utf_8 "UTF-8" 39 | typedef const char* ENCODING_ID; 40 | #define utf8_get_encoding_id_string(desired_enc) ((const char*)desired_enc) 41 | #define utf8_get_encoding_id_from_string(id_string) ((ENCODING_ID)id_string) 42 | 43 | char* utf8_encode(const char *s, int len, int *newlen, ENCODING_ID encoding); 44 | char* utf8_decode(const char *s, int len, int *newlen, ENCODING_ID encoding); 45 | 46 | #endif /* __ENCODINGS__H */ 47 | -------------------------------------------------------------------------------- /tests/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | xmlrpc_encode() Simple test encode array 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | "red", 10 | "two" => "blue", 11 | "three" => "green" 12 | ); 13 | 14 | $response = xmlrpc_encode($params); 15 | echo $response; 16 | 17 | $params = array( 18 | "red", 19 | "blue", 20 | "green" 21 | ); 22 | 23 | $response = xmlrpc_encode($params); 24 | echo $response; 25 | 26 | $params = array( 27 | 0 => "red", 28 | 1 => "blue", 29 | 3 => "green" 30 | ); 31 | 32 | $response = xmlrpc_encode($params); 33 | echo $response; 34 | --EXPECT-- 35 | 36 | 37 | 38 | 39 | 40 | 41 | one 42 | 43 | red 44 | 45 | 46 | 47 | two 48 | 49 | blue 50 | 51 | 52 | 53 | three 54 | 55 | green 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | red 70 | 71 | 72 | blue 73 | 74 | 75 | green 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 0 89 | 90 | red 91 | 92 | 93 | 94 | 1 95 | 96 | blue 97 | 98 | 99 | 100 | 3 101 | 102 | green 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /libxmlrpc/simplestring.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #ifndef __SIMPLESTRING_H__ 34 | #define __SIMPLESTRING_H__ 35 | 36 | /*-******************************** 37 | * begin simplestring header stuff * 38 | **********************************/ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /****s* struct/simplestring 45 | * NAME 46 | * simplestring 47 | * NOTES 48 | * represents a string efficiently for fast appending, etc. 49 | * SOURCE 50 | */ 51 | typedef struct _simplestring { 52 | char* str; /* string buf */ 53 | size_t len; /* length of string/buf */ 54 | size_t size; /* size of allocated buffer */ 55 | } simplestring; 56 | /******/ 57 | 58 | #ifndef NULL 59 | #define NULL 0 60 | #endif 61 | 62 | void simplestring_init(simplestring* string); 63 | void simplestring_clear(simplestring* string); 64 | void simplestring_free(simplestring* string); 65 | void simplestring_add(simplestring* string, const char* add); 66 | void simplestring_addn(simplestring* string, const char* add, size_t add_len); 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | 72 | /*-****************************** 73 | * end simplestring header stuff * 74 | ********************************/ 75 | 76 | #endif /* __SIMPLESTRING_H__ */ 77 | -------------------------------------------------------------------------------- /libxmlrpc/queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Date last modified: Jan 2001 3 | * Modifications by Dan Libby (dan@libby.com), including: 4 | * - various fixes, null checks, etc 5 | * - addition of Q_Iter funcs, macros 6 | */ 7 | 8 | /* 9 | * File : q.h 10 | * 11 | * Peter Yard 02 Jan 1993. 12 | * 13 | * Disclaimer: This code is released to the public domain. 14 | */ 15 | 16 | #ifndef Q__H 17 | #define Q__H 18 | 19 | #ifndef False_ 20 | #define False_ 0 21 | #endif 22 | 23 | #ifndef True_ 24 | #define True_ 1 25 | #endif 26 | 27 | typedef struct nodeptr datanode; 28 | 29 | typedef struct nodeptr { 30 | void *data ; 31 | datanode *prev, *next ; 32 | } node ; 33 | 34 | /* For external use with Q_Iter* funcs */ 35 | typedef struct nodeptr* q_iter; 36 | 37 | typedef struct { 38 | node *head, *tail, *cursor; 39 | int size, sorted, item_deleted; 40 | } queue; 41 | 42 | typedef struct { 43 | void *dataptr; 44 | node *loc ; 45 | } index_elt ; 46 | 47 | 48 | int Q_Init(queue *q); 49 | void Q_Destroy(queue *q); 50 | int Q_IsEmpty(queue *q); 51 | int Q_Size(queue *q); 52 | int Q_AtHead(queue *q); 53 | int Q_AtTail(queue *q); 54 | int Q_PushHead(queue *q, void *d); 55 | int Q_PushTail(queue *q, void *d); 56 | void *Q_Head(queue *q); 57 | void *Q_Tail(queue *q); 58 | void *Q_PopHead(queue *q); 59 | void *Q_PopTail(queue *q); 60 | void *Q_Next(queue *q); 61 | void *Q_Previous(queue *q); 62 | void *Q_DelCur(queue *q); 63 | void *Q_Get(queue *q); 64 | int Q_Put(queue *q, void *data); 65 | int Q_Sort(queue *q, int (*Comp)(const void *, const void *)); 66 | int Q_Find(queue *q, void *data, 67 | int (*Comp)(const void *, const void *)); 68 | void *Q_Seek(queue *q, void *data, 69 | int (*Comp)(const void *, const void *)); 70 | int Q_Insert(queue *q, void *data, 71 | int (*Comp)(const void *, const void *)); 72 | 73 | /* read only funcs for iterating through queue. above funcs modify queue */ 74 | q_iter Q_Iter_Head(queue *q); 75 | q_iter Q_Iter_Tail(queue *q); 76 | q_iter Q_Iter_Next(q_iter qi); 77 | q_iter Q_Iter_Prev(q_iter qi); 78 | void* Q_Iter_Get(q_iter qi); 79 | int Q_Iter_Put(q_iter qi, void* data); /* not read only! here for completeness. */ 80 | void* Q_Iter_Del(queue *q, q_iter iter); /* not read only! here for completeness. */ 81 | 82 | /* Fast (macro'd) versions of above */ 83 | #define Q_Iter_Head_F(q) (q ? (q_iter)((queue*)q)->head : NULL) 84 | #define Q_Iter_Tail_F(q) (q ? (q_iter)((queue*)q)->tail : NULL) 85 | #define Q_Iter_Next_F(qi) (qi ? (q_iter)((node*)qi)->next : NULL) 86 | #define Q_Iter_Prev_F(qi) (qi ? (q_iter)((node*)qi)->prev : NULL) 87 | #define Q_Iter_Get_F(qi) (qi ? ((node*)qi)->data : NULL) 88 | 89 | #endif /* Q__H */ 90 | -------------------------------------------------------------------------------- /php_xmlrpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of, or distributed with, libXMLRPC - a C library for 3 | xml-encoded function calls. 4 | 5 | Author: Dan Libby (dan@libby.com) 6 | Epinions.com may be contacted at feedback@epinions-inc.com 7 | */ 8 | 9 | /* 10 | Copyright 2001 Epinions, Inc. 11 | 12 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 13 | of charge, to (a) use, copy, distribute, modify, perform and display this 14 | software and associated documentation files (the "Software"), and (b) 15 | permit others to whom the Software is furnished to do so as well. 16 | 17 | 1) The above copyright notice and this permission notice shall be included 18 | without modification in all copies or substantial portions of the 19 | Software. 20 | 21 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 22 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 23 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 24 | PURPOSE OR NONINFRINGEMENT. 25 | 26 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 28 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 29 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 30 | DAMAGES. 31 | 32 | */ 33 | 34 | /* auto-generated portions of this file are also subject to the php license */ 35 | 36 | /* 37 | +----------------------------------------------------------------------+ 38 | | Copyright (c) The PHP Group | 39 | +----------------------------------------------------------------------+ 40 | | This source file is subject to version 3.01 of the PHP license, | 41 | | that is bundled with this package in the file LICENSE, and is | 42 | | available through the world-wide-web at the following url: | 43 | | http://www.php.net/license/3_01.txt | 44 | | If you did not receive a copy of the PHP license and are unable to | 45 | | obtain it through the world-wide-web, please send a note to | 46 | | license@php.net so we can mail you a copy immediately. | 47 | +----------------------------------------------------------------------+ 48 | | Author: Dan Libby | 49 | +----------------------------------------------------------------------+ 50 | */ 51 | 52 | #ifndef _PHP_XMLRPC_H 53 | #define _PHP_XMLRPC_H 54 | 55 | #if 1 /* HAVE_XMLRPC */ 56 | 57 | extern zend_module_entry xmlrpc_module_entry; 58 | #define phpext_xmlrpc_ptr &xmlrpc_module_entry 59 | 60 | #include "php_version.h" 61 | #define PHP_XMLRPC_VERSION "1.0.0RC3" 62 | 63 | PHP_MINIT_FUNCTION(xmlrpc); 64 | PHP_MINFO_FUNCTION(xmlrpc); 65 | 66 | #else 67 | 68 | #define phpext_xmlrpc_ptr NULL 69 | 70 | #endif 71 | 72 | #endif /* _PHP_XMLRPC_H */ 73 | -------------------------------------------------------------------------------- /tests/bug50285.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Bug #50285 (xmlrpc does not preserve keys in encoded indexed arrays) 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 'One', 3=>'Three', 5=>'Five'); 10 | } 11 | 12 | function test2($func, $params) { 13 | return array('One', 'Three', 'Five', 5); 14 | } 15 | 16 | function test3($func, $params) { 17 | return array('One', 3 => 'Three', 'Five' => 5, 'Six'); 18 | } 19 | 20 | function test4($func, $params) { 21 | return array('One', 'Three', 'Five', 'Six' => 6); 22 | } 23 | 24 | $server = xmlrpc_server_create(); 25 | $result = xmlrpc_server_register_method($server, 'test1', 'test1'); 26 | $HTTP_RAW_POST_DATA = << 28 | 29 | test1 30 | 31 | 32 | EOD; 33 | $response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); 34 | var_dump(xmlrpc_decode($response)); 35 | 36 | // ------------ 37 | 38 | $server = xmlrpc_server_create(); 39 | $result = xmlrpc_server_register_method($server, 'test2', 'test2'); 40 | $HTTP_RAW_POST_DATA = << 42 | 43 | test2 44 | 45 | 46 | EOD; 47 | $response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); 48 | var_dump(xmlrpc_decode($response)); 49 | 50 | // ------------ 51 | 52 | $server = xmlrpc_server_create(); 53 | $result = xmlrpc_server_register_method($server, 'test3', 'test3'); 54 | $HTTP_RAW_POST_DATA = << 56 | 57 | test3 58 | 59 | 60 | EOD; 61 | $response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); 62 | var_dump(xmlrpc_decode($response)); 63 | 64 | // ------------ 65 | 66 | $server = xmlrpc_server_create(); 67 | $result = xmlrpc_server_register_method($server, 'test4', 'test4'); 68 | $HTTP_RAW_POST_DATA = << 70 | 71 | test4 72 | 73 | 74 | EOD; 75 | $response = xmlrpc_server_call_method($server, $HTTP_RAW_POST_DATA, null); 76 | var_dump(xmlrpc_decode($response)); 77 | 78 | ?> 79 | --EXPECT-- 80 | array(3) { 81 | [1]=> 82 | string(3) "One" 83 | [3]=> 84 | string(5) "Three" 85 | [5]=> 86 | string(4) "Five" 87 | } 88 | array(4) { 89 | [0]=> 90 | string(3) "One" 91 | [1]=> 92 | string(5) "Three" 93 | [2]=> 94 | string(4) "Five" 95 | [3]=> 96 | int(5) 97 | } 98 | array(4) { 99 | [0]=> 100 | string(3) "One" 101 | [3]=> 102 | string(5) "Three" 103 | ["Five"]=> 104 | int(5) 105 | [4]=> 106 | string(3) "Six" 107 | } 108 | array(4) { 109 | [0]=> 110 | string(3) "One" 111 | [1]=> 112 | string(5) "Three" 113 | [2]=> 114 | string(4) "Five" 115 | ["Six"]=> 116 | int(6) 117 | } 118 | -------------------------------------------------------------------------------- /libxmlrpc/system_methods_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2001 Dan Libby, Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | /* IMPORTANT! 34 | * 35 | * only non-public things should be in this file. It is fine for any .c file 36 | * in xmlrpc/src to include it, but users of the public API should never 37 | * include it, and thus *.h files that are part of the public API should 38 | * never include it, or they would break if this file is not present. 39 | */ 40 | 41 | 42 | #ifndef __SYSTEM_METHODS_PRIVATE_H 43 | /* 44 | * Avoid include redundancy. 45 | */ 46 | #define __SYSTEM_METHODS_PRIVATE_H 47 | 48 | /*---------------------------------------------------------------------------- 49 | * system_methods_private.h 50 | * 51 | * Purpose: 52 | * define non-public system.* methods 53 | * Comments: 54 | * xsm = xmlrpc system methods 55 | */ 56 | 57 | /*---------------------------------------------------------------------------- 58 | * Constants 59 | */ 60 | #define xsm_token_system_multicall "system.multiCall" 61 | #define xsm_token_system_get_capabilities "system.getCapabilities" 62 | 63 | 64 | /*---------------------------------------------------------------------------- 65 | * Includes 66 | */ 67 | 68 | /*---------------------------------------------------------------------------- 69 | * Structures 70 | */ 71 | 72 | /*---------------------------------------------------------------------------- 73 | * Globals 74 | */ 75 | 76 | /*---------------------------------------------------------------------------- 77 | * Functions 78 | */ 79 | void xsm_register(XMLRPC_SERVER server); 80 | int xsm_is_system_method(XMLRPC_Callback cb); 81 | 82 | /*---------------------------------------------------------------------------- 83 | * Macros 84 | */ 85 | 86 | 87 | #endif /* __SYSTEM_METHODS_PRIVATE_H */ 88 | -------------------------------------------------------------------------------- /libxmlrpc/xmlrpc_introspection.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | /* IMPORTANT! 34 | * 35 | * only public (official API) things should be in this file. Anything else 36 | * should go in _private.h, or in the appropriate .c file. 37 | */ 38 | 39 | 40 | #ifndef __XI_INTROSPECTION_H 41 | /* 42 | * Avoid include redundancy. 43 | */ 44 | #define __XI_INTROSPECTION_H 45 | 46 | /*---------------------------------------------------------------------------- 47 | * xmlrpc_introspection.h 48 | * 49 | * Purpose: 50 | * define public introspection API 51 | * Comments: 52 | */ 53 | 54 | /*---------------------------------------------------------------------------- 55 | * Constants 56 | */ 57 | #define xi_token_params "params" 58 | #define xi_token_returns "returns" 59 | #define xi_token_related "related" 60 | #define xi_token_sub "sub" 61 | 62 | 63 | /*---------------------------------------------------------------------------- 64 | * Includes 65 | */ 66 | 67 | /*---------------------------------------------------------------------------- 68 | * Structures 69 | */ 70 | 71 | /****d* VALUE/XMLRPC_IntrospectionCallback 72 | * NAME 73 | * XMLRPC_IntrospectionCallback 74 | * NOTES 75 | * Function prototype for lazy documentation generation (not generated until requested). 76 | * SOURCE 77 | */ 78 | typedef void (*XMLRPC_IntrospectionCallback)(XMLRPC_SERVER server, void* userData); 79 | /******/ 80 | 81 | 82 | /*---------------------------------------------------------------------------- 83 | * Globals 84 | */ 85 | 86 | /*---------------------------------------------------------------------------- 87 | * Functions 88 | */ 89 | XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR error); 90 | int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc); 91 | int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb); 92 | 93 | /*---------------------------------------------------------------------------- 94 | * Macros 95 | */ 96 | 97 | 98 | #endif /* __XI_INTROSPECTION_H */ 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, version 3.01 3 | Copyright (c) 1999 - 2019 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, is permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | 3. The name "PHP" must not be used to endorse or promote products 19 | derived from this software without prior written permission. For 20 | written permission, please contact group@php.net. 21 | 22 | 4. Products derived from this software may not be called "PHP", nor 23 | may "PHP" appear in their name, without prior written permission 24 | from group@php.net. You may indicate that your software works in 25 | conjunction with PHP by saying "Foo for PHP" instead of calling 26 | it "PHP Foo" or "phpfoo" 27 | 28 | 5. The PHP Group may publish revised and/or new versions of the 29 | license from time to time. Each version will be given a 30 | distinguishing version number. 31 | Once covered code has been published under a particular version 32 | of the license, you may always continue to use it under the terms 33 | of that version. You may also choose to use such covered code 34 | under the terms of any subsequent version of the license 35 | published by the PHP Group. No one other than the PHP Group has 36 | the right to modify the terms applicable to covered code created 37 | under this License. 38 | 39 | 6. Redistributions of any form whatsoever must retain the following 40 | acknowledgment: 41 | "This product includes PHP software, freely available from 42 | ". 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND 45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP 48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | OF THE POSSIBILITY OF SUCH DAMAGE. 56 | 57 | -------------------------------------------------------------------- 58 | 59 | This software consists of voluntary contributions made by many 60 | individuals on behalf of the PHP Group. 61 | 62 | The PHP Group can be contacted via Email at group@php.net. 63 | 64 | For more information on the PHP Group and the PHP project, 65 | please see . 66 | 67 | PHP includes the Zend Engine, freely available at 68 | . 69 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_WITH([xmlrpc], 2 | [whether to build with XMLRPC-EPI support], 3 | [AS_HELP_STRING([[--with-xmlrpc[=DIR]]], 4 | [Include XMLRPC-EPI support])]) 5 | 6 | PHP_ARG_WITH([expat], 7 | [whether to build with expat support], 8 | [AS_HELP_STRING([--with-expat], 9 | [XMLRPC-EPI: use expat instead of libxml2])], 10 | [no], 11 | [no]) 12 | 13 | PHP_ARG_WITH([iconv-dir], 14 | [iconv dir for XMLRPC-EPI], 15 | [AS_HELP_STRING([--with-iconv-dir=DIR], 16 | [XMLRPC-EPI: iconv dir for XMLRPC-EPI])], 17 | [no], 18 | [no]) 19 | 20 | if test "$PHP_XMLRPC" != "no"; then 21 | 22 | PHP_ADD_EXTENSION_DEP(xmlrpc, libxml) 23 | PHP_SUBST(XMLRPC_SHARED_LIBADD) 24 | AC_DEFINE(HAVE_XMLRPC,1,[ ]) 25 | 26 | dnl 27 | dnl Default to libxml2 if --with-expat is not specified. 28 | dnl 29 | if test "$PHP_EXPAT" = "no"; then 30 | 31 | if test "$PHP_LIBXML" = "no"; then 32 | AC_MSG_ERROR([XML-RPC extension requires LIBXML extension, add --with-libxml]) 33 | fi 34 | 35 | PHP_SETUP_LIBXML(XMLRPC_SHARED_LIBADD, [ 36 | if test "$PHP_XML" = "no"; then 37 | PHP_ADD_SOURCES(ext/xml, compat.c) 38 | PHP_ADD_BUILD_DIR(ext/xml) 39 | fi 40 | ]) 41 | else 42 | PHP_SETUP_EXPAT([XMLRPC_SHARED_LIBADD]) 43 | fi 44 | 45 | dnl if iconv is shared or missing then we should build iconv ourselves 46 | if test "$PHP_ICONV_SHARED" = "yes" || test "$PHP_ICONV" = "no"; then 47 | 48 | if test "$PHP_ICONV_DIR" != "no"; then 49 | PHP_ICONV=$PHP_ICONV_DIR 50 | fi 51 | 52 | if test -z "$PHP_ICONV" || test "$PHP_ICONV" = "no"; then 53 | PHP_ICONV=yes 54 | fi 55 | 56 | PHP_SETUP_ICONV(XMLRPC_SHARED_LIBADD, [], [ 57 | AC_MSG_ERROR([iconv not found, in order to build xmlrpc you need the iconv library]) 58 | ]) 59 | fi 60 | fi 61 | 62 | if test "$PHP_XMLRPC" = "yes"; then 63 | PHP_NEW_EXTENSION(xmlrpc,xmlrpc-epi-php.c libxmlrpc/base64.c \ 64 | libxmlrpc/simplestring.c libxmlrpc/xml_to_dandarpc.c \ 65 | libxmlrpc/xmlrpc_introspection.c libxmlrpc/encodings.c \ 66 | libxmlrpc/system_methods.c libxmlrpc/xml_to_xmlrpc.c \ 67 | libxmlrpc/queue.c libxmlrpc/xml_element.c libxmlrpc/xmlrpc.c \ 68 | libxmlrpc/xml_to_soap.c,$ext_shared,, 69 | -I@ext_srcdir@/libxmlrpc -DVERSION="0.50") 70 | PHP_ADD_BUILD_DIR($ext_builddir/libxmlrpc) 71 | XMLRPC_MODULE_TYPE=builtin 72 | AC_DEFINE(HAVE_XMLRPC_BUNDLED, 1, [ ]) 73 | 74 | elif test "$PHP_XMLRPC" != "no"; then 75 | 76 | if test -r $PHP_XMLRPC/include/xmlrpc.h; then 77 | XMLRPC_DIR=$PHP_XMLRPC/include 78 | elif test -r $PHP_XMLRPC/include/xmlrpc-epi/xmlrpc.h; then 79 | dnl Some xmlrpc-epi header files have generic file names like queue.h or 80 | dnl base64.h. Distributions have to create dir for xmlrpc-epi because of 81 | dnl this. 82 | XMLRPC_DIR=$PHP_XMLRPC/include/xmlrpc-epi 83 | else 84 | AC_MSG_CHECKING(for XMLRPC-EPI in default path) 85 | for i in /usr/local /usr; do 86 | if test -r $i/include/xmlrpc.h; then 87 | XMLRPC_DIR=$i/include 88 | AC_MSG_RESULT(found in $i) 89 | break 90 | fi 91 | done 92 | fi 93 | 94 | if test -z "$XMLRPC_DIR"; then 95 | AC_MSG_RESULT(not found) 96 | AC_MSG_ERROR(Please reinstall the XMLRPC-EPI distribution) 97 | fi 98 | 99 | PHP_ADD_INCLUDE($XMLRPC_DIR) 100 | PHP_ADD_LIBRARY_WITH_PATH(xmlrpc, $XMLRPC_DIR/$PHP_LIBDIR, XMLRPC_SHARED_LIBADD) 101 | PHP_NEW_EXTENSION(xmlrpc,xmlrpc-epi-php.c, $ext_shared) 102 | XMLRPC_MODULE_TYPE=external 103 | fi 104 | 105 | PHP_ADD_MAKEFILE_FRAGMENT 106 | -------------------------------------------------------------------------------- /libxmlrpc/encodings.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | #ifdef HAVE_GICONV_H 39 | #include 40 | #else 41 | #include 42 | #endif 43 | 44 | #include "encodings.h" 45 | 46 | #ifndef ICONV_CSNMAXLEN 47 | #define ICONV_CSNMAXLEN 64 48 | #endif 49 | 50 | static char* convert(const char* src, int src_len, int *new_len, const char* from_enc, const char* to_enc) { 51 | char* outbuf = 0; 52 | 53 | if(src && src_len && from_enc && to_enc) { 54 | size_t outlenleft = src_len; 55 | size_t inlenleft = src_len; 56 | int outlen = src_len; 57 | iconv_t ic; 58 | char* out_ptr = 0; 59 | 60 | if(strlen(to_enc) >= ICONV_CSNMAXLEN || strlen(from_enc) >= ICONV_CSNMAXLEN) { 61 | return NULL; 62 | } 63 | ic = iconv_open(to_enc, from_enc); 64 | if(ic != (iconv_t)-1) { 65 | size_t st; 66 | outbuf = (char*)emalloc(outlen + 1); 67 | 68 | out_ptr = (char*)outbuf; 69 | while(inlenleft) { 70 | st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft); 71 | if(st == -1) { 72 | if(errno == E2BIG) { 73 | int diff = out_ptr - outbuf; 74 | outlen += inlenleft; 75 | outlenleft += inlenleft; 76 | outbuf = (char*)erealloc(outbuf, outlen + 1); 77 | out_ptr = outbuf + diff; 78 | } 79 | else { 80 | efree(outbuf); 81 | outbuf = 0; 82 | break; 83 | } 84 | } 85 | } 86 | iconv_close(ic); 87 | } 88 | outlen -= outlenleft; 89 | 90 | if(new_len) { 91 | *new_len = outbuf ? outlen : 0; 92 | } 93 | if(outbuf) { 94 | outbuf[outlen] = 0; 95 | } 96 | } 97 | return outbuf; 98 | } 99 | 100 | /* returns a new string that must be freed */ 101 | char* utf8_encode(const char *s, int len, int *newlen, const char* encoding) 102 | { 103 | return convert(s, len, newlen, encoding, "UTF-8"); 104 | } 105 | 106 | /* returns a new string, possibly decoded */ 107 | char* utf8_decode(const char *s, int len, int *newlen, const char* encoding) 108 | { 109 | return convert(s, len, newlen, "UTF-8", encoding); 110 | } 111 | -------------------------------------------------------------------------------- /libxmlrpc/xmlrpc_introspection_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2001 Dan Libby, Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | /* IMPORTANT! 34 | * 35 | * only non-public things should be in this file. It is fine for any .c file 36 | * in xmlrpc/src to include it, but users of the public API should never 37 | * include it, and thus *.h files that are part of the public API should 38 | * never include it, or they would break if this file is not present. 39 | */ 40 | 41 | 42 | #ifndef __XI_INTROSPECTION_PRIVATE_H 43 | /* 44 | * Avoid include redundancy. 45 | */ 46 | #define __XI_INTROSPECTION_PRIVATE_H 47 | 48 | /*---------------------------------------------------------------------------- 49 | * xmlrpc_introspection_private.h 50 | * 51 | * Purpose: 52 | * define non-public introspection routines 53 | * Comments: 54 | */ 55 | 56 | /*---------------------------------------------------------------------------- 57 | * Constants 58 | */ 59 | #define xi_token_default "default" 60 | #define xi_token_description "description" 61 | #define xi_token_name "name" 62 | #define xi_token_optional "optional" 63 | #define xi_token_params "params" 64 | #define xi_token_purpose "purpose" 65 | #define xi_token_returns "returns" 66 | #define xi_token_signatures "signatures" 67 | #define xi_token_type "type" 68 | #define xi_token_version "version" 69 | #define xi_token_empty "" 70 | #define xi_token_system_describe_methods "system.describeMethods" 71 | #define xi_token_system_list_methods "system.listMethods" 72 | #define xi_token_system_method_help "system.methodHelp" 73 | #define xi_token_system_method_signature "system.methodSignature" 74 | 75 | 76 | /*---------------------------------------------------------------------------- 77 | * Includes 78 | */ 79 | 80 | /*---------------------------------------------------------------------------- 81 | * Structures 82 | */ 83 | typedef struct _doc_method { 84 | XMLRPC_IntrospectionCallback method; 85 | int b_called; 86 | } doc_method; 87 | 88 | /*---------------------------------------------------------------------------- 89 | * Globals 90 | */ 91 | 92 | /*---------------------------------------------------------------------------- 93 | * Functions 94 | */ 95 | void xi_register_system_methods(XMLRPC_SERVER server); 96 | 97 | /*---------------------------------------------------------------------------- 98 | * Macros 99 | */ 100 | 101 | 102 | #endif /* __XI_INTROSPECTION_PRIVATE_H */ 103 | -------------------------------------------------------------------------------- /libxmlrpc/base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Encode or decode file as MIME base64 (RFC 1341) 4 | 5 | by John Walker 6 | http://www.fourmilab.ch/ 7 | 8 | This program is in the public domain. 9 | 10 | */ 11 | #include 12 | 13 | /* ENCODE -- Encode binary file into base64. */ 14 | #include 15 | #include 16 | #include 17 | 18 | #include "base64.h" 19 | 20 | static unsigned char dtable[512]; 21 | 22 | void buffer_new(struct buffer_st *b) 23 | { 24 | b->length = 512; 25 | b->data = emalloc(sizeof(char)*(b->length)); 26 | b->data[0] = 0; 27 | b->ptr = b->data; 28 | b->offset = 0; 29 | } 30 | 31 | void buffer_add(struct buffer_st *b, char c) 32 | { 33 | if ((INT_MAX - b->length) <= 512) { 34 | return; 35 | } 36 | *(b->ptr++) = c; 37 | b->offset++; 38 | if (b->offset == b->length) { 39 | b->length += 512; 40 | b->data = erealloc(b->data, b->length); 41 | b->ptr = b->data + b->offset; 42 | } 43 | } 44 | 45 | void buffer_delete(struct buffer_st *b) 46 | { 47 | efree(b->data); 48 | b->length = 0; 49 | b->offset = 0; 50 | b->ptr = NULL; 51 | b->data = NULL; 52 | } 53 | 54 | void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length) 55 | { 56 | int i, hiteof = 0; 57 | int offset = 0; 58 | 59 | buffer_new(b); 60 | 61 | /* Fill dtable with character encodings. */ 62 | 63 | for (i = 0; i < 26; i++) { 64 | dtable[i] = 'A' + i; 65 | dtable[26 + i] = 'a' + i; 66 | } 67 | for (i = 0; i < 10; i++) { 68 | dtable[52 + i] = '0' + i; 69 | } 70 | dtable[62] = '+'; 71 | dtable[63] = '/'; 72 | 73 | while (!hiteof) { 74 | unsigned char igroup[3], ogroup[4]; 75 | int c, n; 76 | 77 | igroup[0] = igroup[1] = igroup[2] = 0; 78 | for (n = 0; n < 3; n++) { 79 | c = *(source++); 80 | offset++; 81 | if (offset > length || offset <= 0) { 82 | hiteof = 1; 83 | break; 84 | } 85 | igroup[n] = (unsigned char) c; 86 | } 87 | if (n > 0) { 88 | ogroup[0] = dtable[igroup[0] >> 2]; 89 | ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 90 | ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 91 | ogroup[3] = dtable[igroup[2] & 0x3F]; 92 | 93 | /* Replace characters in output stream with "=" pad 94 | characters if fewer than three characters were 95 | read from the end of the input stream. */ 96 | 97 | if (n < 3) { 98 | ogroup[3] = '='; 99 | if (n < 2) { 100 | ogroup[2] = '='; 101 | } 102 | } 103 | for (i = 0; i < 4; i++) { 104 | buffer_add(b, ogroup[i]); 105 | if (!(b->offset % 72)) { 106 | /* buffer_add(b, '\r'); */ 107 | buffer_add(b, '\n'); 108 | } 109 | } 110 | } 111 | } 112 | /* buffer_add(b, '\r'); */ 113 | buffer_add(b, '\n'); 114 | } 115 | 116 | void base64_decode_xmlrpc(struct buffer_st *bfr, const char *source, int length) 117 | { 118 | int i; 119 | int offset = 0; 120 | int endoffile; 121 | int count; 122 | 123 | buffer_new(bfr); 124 | 125 | for (i = 0; i < 255; i++) { 126 | dtable[i] = 0x80; 127 | } 128 | for (i = 'A'; i <= 'Z'; i++) { 129 | dtable[i] = 0 + (i - 'A'); 130 | } 131 | for (i = 'a'; i <= 'z'; i++) { 132 | dtable[i] = 26 + (i - 'a'); 133 | } 134 | for (i = '0'; i <= '9'; i++) { 135 | dtable[i] = 52 + (i - '0'); 136 | } 137 | dtable['+'] = 62; 138 | dtable['/'] = 63; 139 | dtable['='] = 0; 140 | 141 | endoffile = 0; 142 | 143 | /*CONSTANTCONDITION*/ 144 | while (1) { 145 | unsigned char a[4], b[4], o[3]; 146 | 147 | for (i = 0; i < 4; i++) { 148 | int c; 149 | while (1) { 150 | c = *(source++); 151 | offset++; 152 | if (offset > length) endoffile = 1; 153 | if (isspace(c) || c == '\n' || c == '\r') continue; 154 | break; 155 | } 156 | 157 | if (endoffile) { 158 | /* 159 | if (i > 0) { 160 | fprintf(stderr, "Input file incomplete.\n"); 161 | exit(1); 162 | } 163 | */ 164 | return; 165 | } 166 | 167 | if (dtable[(unsigned char)c] & 0x80) { 168 | /* 169 | fprintf(stderr, "Offset %i length %i\n", offset, length); 170 | fprintf(stderr, "character '%c:%x:%c' in input file.\n", c, c, dtable[c]); 171 | exit(1); 172 | */ 173 | i--; 174 | continue; 175 | } 176 | a[i] = (unsigned char) c; 177 | b[i] = (unsigned char) dtable[c]; 178 | } 179 | o[0] = (b[0] << 2) | (b[1] >> 4); 180 | o[1] = (b[1] << 4) | (b[2] >> 2); 181 | o[2] = (b[2] << 6) | b[3]; 182 | i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); 183 | count = 0; 184 | while (count < i) { 185 | buffer_add(bfr, o[count++]); 186 | } 187 | if (i < 3) { 188 | return; 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /xmlrpc_arginfo.h: -------------------------------------------------------------------------------- 1 | /* This is a generated file, edit the .stub.php file instead. 2 | * Stub hash: 2c5da90cd5f2c426f268a392171339bdf268e293 */ 3 | 4 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_encode, 0, 1, IS_STRING, 1) 5 | ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) 6 | ZEND_END_ARG_INFO() 7 | 8 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_decode, 0, 1, IS_MIXED, 0) 9 | ZEND_ARG_TYPE_INFO(0, xml, IS_STRING, 0) 10 | ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"iso-8859-1\"") 11 | ZEND_END_ARG_INFO() 12 | 13 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_decode_request, 0, 2, IS_MIXED, 0) 14 | ZEND_ARG_TYPE_INFO(0, xml, IS_STRING, 0) 15 | ZEND_ARG_INFO(1, method) 16 | ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"iso-8859-1\"") 17 | ZEND_END_ARG_INFO() 18 | 19 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_encode_request, 0, 2, IS_STRING, 1) 20 | ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 1) 21 | ZEND_ARG_TYPE_INFO(0, params, IS_MIXED, 0) 22 | ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, output_options, IS_ARRAY, 0, "[]") 23 | ZEND_END_ARG_INFO() 24 | 25 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_get_type, 0, 1, IS_STRING, 0) 26 | ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) 27 | ZEND_END_ARG_INFO() 28 | 29 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_set_type, 0, 2, _IS_BOOL, 0) 30 | ZEND_ARG_INFO(1, value) 31 | ZEND_ARG_TYPE_INFO(0, type, IS_STRING, 0) 32 | ZEND_END_ARG_INFO() 33 | 34 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_is_fault, 0, 1, _IS_BOOL, 0) 35 | ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) 36 | ZEND_END_ARG_INFO() 37 | 38 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_xmlrpc_server_create, 0, 0, XmlRpcServer, 0) 39 | ZEND_END_ARG_INFO() 40 | 41 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_destroy, 0, 1, _IS_BOOL, 0) 42 | ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0) 43 | ZEND_END_ARG_INFO() 44 | 45 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_register_method, 0, 3, _IS_BOOL, 0) 46 | ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0) 47 | ZEND_ARG_TYPE_INFO(0, method_name, IS_STRING, 0) 48 | ZEND_ARG_INFO(0, function) 49 | ZEND_END_ARG_INFO() 50 | 51 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_call_method, 0, 3, IS_MIXED, 0) 52 | ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0) 53 | ZEND_ARG_TYPE_INFO(0, xml, IS_STRING, 0) 54 | ZEND_ARG_TYPE_INFO(0, user_data, IS_MIXED, 0) 55 | ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, output_options, IS_ARRAY, 0, "[]") 56 | ZEND_END_ARG_INFO() 57 | 58 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_parse_method_descriptions, 0, 1, IS_MIXED, 0) 59 | ZEND_ARG_TYPE_INFO(0, xml, IS_STRING, 0) 60 | ZEND_END_ARG_INFO() 61 | 62 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_add_introspection_data, 0, 2, IS_LONG, 0) 63 | ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0) 64 | ZEND_ARG_TYPE_INFO(0, desc, IS_ARRAY, 0) 65 | ZEND_END_ARG_INFO() 66 | 67 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_xmlrpc_server_register_introspection_callback, 0, 2, _IS_BOOL, 0) 68 | ZEND_ARG_OBJ_INFO(0, server, XmlRpcServer, 0) 69 | ZEND_ARG_INFO(0, function) 70 | ZEND_END_ARG_INFO() 71 | 72 | 73 | ZEND_FUNCTION(xmlrpc_encode); 74 | ZEND_FUNCTION(xmlrpc_decode); 75 | ZEND_FUNCTION(xmlrpc_decode_request); 76 | ZEND_FUNCTION(xmlrpc_encode_request); 77 | ZEND_FUNCTION(xmlrpc_get_type); 78 | ZEND_FUNCTION(xmlrpc_set_type); 79 | ZEND_FUNCTION(xmlrpc_is_fault); 80 | ZEND_FUNCTION(xmlrpc_server_create); 81 | ZEND_FUNCTION(xmlrpc_server_destroy); 82 | ZEND_FUNCTION(xmlrpc_server_register_method); 83 | ZEND_FUNCTION(xmlrpc_server_call_method); 84 | ZEND_FUNCTION(xmlrpc_parse_method_descriptions); 85 | ZEND_FUNCTION(xmlrpc_server_add_introspection_data); 86 | ZEND_FUNCTION(xmlrpc_server_register_introspection_callback); 87 | 88 | 89 | static const zend_function_entry ext_functions[] = { 90 | ZEND_FE(xmlrpc_encode, arginfo_xmlrpc_encode) 91 | ZEND_FE(xmlrpc_decode, arginfo_xmlrpc_decode) 92 | ZEND_FE(xmlrpc_decode_request, arginfo_xmlrpc_decode_request) 93 | ZEND_FE(xmlrpc_encode_request, arginfo_xmlrpc_encode_request) 94 | ZEND_FE(xmlrpc_get_type, arginfo_xmlrpc_get_type) 95 | ZEND_FE(xmlrpc_set_type, arginfo_xmlrpc_set_type) 96 | ZEND_FE(xmlrpc_is_fault, arginfo_xmlrpc_is_fault) 97 | ZEND_FE(xmlrpc_server_create, arginfo_xmlrpc_server_create) 98 | ZEND_FE(xmlrpc_server_destroy, arginfo_xmlrpc_server_destroy) 99 | ZEND_FE(xmlrpc_server_register_method, arginfo_xmlrpc_server_register_method) 100 | ZEND_FE(xmlrpc_server_call_method, arginfo_xmlrpc_server_call_method) 101 | ZEND_FE(xmlrpc_parse_method_descriptions, arginfo_xmlrpc_parse_method_descriptions) 102 | ZEND_FE(xmlrpc_server_add_introspection_data, arginfo_xmlrpc_server_add_introspection_data) 103 | ZEND_FE(xmlrpc_server_register_introspection_callback, arginfo_xmlrpc_server_register_introspection_callback) 104 | ZEND_FE_END 105 | }; 106 | 107 | 108 | static const zend_function_entry class_XmlRpcServer_methods[] = { 109 | ZEND_FE_END 110 | }; 111 | -------------------------------------------------------------------------------- /libxmlrpc/xmlrpc_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | /* only non-public things should be in this file. It is fine for any .c file 34 | * in xmlrpc/src to include it, but users of the public API should never 35 | * include it, and thus *.h files that are part of the public API should 36 | * never include it, or they would break if this file is not present. 37 | */ 38 | 39 | #ifndef XMLRPC_PRIVATE_ALREADY_INCLUDED 40 | /* 41 | * Avoid include redundancy. 42 | */ 43 | #define XMLRPC_PRIVATE_ALREADY_INCLUDED 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | 50 | /*---------------------------------------------------------------------------- 51 | * xmlrpc_private.h 52 | * 53 | * Purpose: 54 | * define non-public intra-library routines & data 55 | * Comments: 56 | */ 57 | 58 | /*---------------------------------------------------------------------------- 59 | * Constants 60 | */ 61 | 62 | 63 | /*---------------------------------------------------------------------------- 64 | * Includes 65 | */ 66 | 67 | /*---------------------------------------------------------------------------- 68 | * Structures 69 | */ 70 | 71 | /* Some of these are typedef'd in xmlrpc.h for public use */ 72 | 73 | typedef struct _xmlrpc_vector* XMLRPC_VECTOR; 74 | 75 | /****s* VALUE/XMLRPC_VALUE 76 | * NAME 77 | * XMLRPC_VALUE 78 | * NOTES 79 | * A value of variable data type. The most important object in this API. :) 80 | * 81 | * This struct is opaque to callers and should be accessed only via accessor functions. 82 | * SEE ALSO 83 | * XMLRPC_REQUEST 84 | * XMLRPC_CreateValueEmpty () 85 | * XMLRPC_CleanupValue () 86 | * SOURCE 87 | */ 88 | typedef struct _xmlrpc_value { 89 | XMLRPC_VALUE_TYPE type; /* data type of this value */ 90 | XMLRPC_VECTOR v; /* vector type specific info */ 91 | simplestring str; /* string value buffer */ 92 | simplestring id; /* id of this value. possibly empty. */ 93 | int i; /* integer value. */ 94 | double d; /* double value */ 95 | int iRefCount; /* So we know when we can delete the value . */ 96 | } STRUCT_XMLRPC_VALUE; 97 | /******/ 98 | 99 | /****s* VALUE/XMLRPC_REQUEST 100 | * NAME 101 | * XMLRPC_REQUEST 102 | * NOTES 103 | * Internal representation of an XML request. 104 | * 105 | * This struct is opaque to callers and should be accessed only via accessor functions. 106 | * 107 | * SEE ALSO 108 | * XMLRPC_VALUE 109 | * XMLRPC_RequestNew () 110 | * XMLRPC_RequestFree () 111 | * SOURCE 112 | */ 113 | typedef struct _xmlrpc_request { 114 | XMLRPC_VALUE io; /* data associated with this request */ 115 | simplestring methodName; /* name of method being called */ 116 | XMLRPC_REQUEST_TYPE request_type; /* type of request */ 117 | STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS output; /* xml output options */ 118 | XMLRPC_VALUE error; /* error codes */ 119 | } STRUCT_XMLRPC_REQUEST; 120 | /******/ 121 | 122 | /* Vector type. Used by XMLRPC_VALUE. Never visible to users of the API. */ 123 | typedef struct _xmlrpc_vector { 124 | XMLRPC_VECTOR_TYPE type; /* vector type */ 125 | queue *q; /* list of child values */ 126 | } STRUCT_XMLRPC_VECTOR; 127 | /******/ 128 | 129 | /****s* VALUE/XMLRPC_SERVER 130 | * NAME 131 | * XMLRPC_SERVER 132 | * NOTES 133 | * internal representation of an xmlrpc server 134 | * 135 | * This struct is opaque to callers and should be accessed only via accessor functions. 136 | * 137 | * SEE ALSO 138 | * XMLRPC_ServerCreate () 139 | * XMLRPC_ServerDestroy () 140 | * SOURCE 141 | */ 142 | typedef struct _xmlrpc_server { 143 | queue methodlist; /* list of callback methods */ 144 | queue docslist; /* list of introspection callbacks */ 145 | XMLRPC_VALUE xIntrospection; 146 | } STRUCT_XMLRPC_SERVER; 147 | /******/ 148 | 149 | typedef struct _server_method { 150 | char* name; 151 | XMLRPC_VALUE desc; 152 | XMLRPC_Callback method; 153 | } server_method; 154 | 155 | 156 | /*---------------------------------------------------------------------------- 157 | * Globals 158 | */ 159 | 160 | /*---------------------------------------------------------------------------- 161 | * Functions 162 | */ 163 | server_method* find_method(XMLRPC_SERVER server, const char* name); 164 | const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype); 165 | 166 | /*---------------------------------------------------------------------------- 167 | * Macros 168 | */ 169 | #define my_free(thing) if(thing) {efree(thing); thing = 0;} 170 | 171 | 172 | #ifdef __cplusplus 173 | } 174 | #endif 175 | 176 | 177 | #endif /* XMLRPC_PRIVATE_ALREADY_INCLUDED */ 178 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | xmlrpc 7 | pecl.php.net 8 | Functions to write XML-RPC servers and clients 9 | 10 | These functions can be used to write XML-RPC servers and clients. You can find 11 | more information about XML-RPC at http://www.xmlrpc.com/, and more documentation 12 | on this extension and its functions at http://xmlrpc-epi.sourceforge.net/. 13 | 14 | The extension is unbundled from php-src as of PHP 8.0.0, because the underlying 15 | libxmlrpc has obviously been abandoned. It is recommended to reevaluate using 16 | this extension. 17 | 18 | 19 | Christoph M. Becker 20 | cmb 21 | cmbecker69@gmx.de 22 | yes 23 | 24 | 2021-12-04 25 | 26 | 1.0.0RC3 27 | 1.0 28 | 29 | 30 | beta 31 | beta 32 | 33 | PHP 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 8.0.0 122 | 123 | 124 | 1.4.0b1 125 | 126 | 127 | 128 | xmlrpc 129 | 130 | 131 | 132 | 2021-01-15 133 | 134 | 1.0.0RC2 135 | 1.0 136 | 137 | 138 | beta 139 | beta 140 | 141 | PHP 142 | 143 | 147 | 148 | 149 | 150 | 2021-01-04 151 | 152 | 1.0.0RC1 153 | 1.0 154 | 155 | 156 | beta 157 | beta 158 | 159 | PHP 160 | 161 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /libxmlrpc/xml_element.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #ifndef __XML_ELEMENT_H__ 34 | #define __XML_ELEMENT_H__ 35 | 36 | /* includes */ 37 | #include 38 | #include "queue.h" 39 | #include "simplestring.h" 40 | #include "encodings.h" 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /****d* enum/XML_ELEM_VERBOSITY 47 | * NAME 48 | * XML_ELEM_VERBOSITY 49 | * NOTES 50 | * verbosity/readability options for generated xml 51 | * SEE ALSO 52 | * XML_ELEM_OUTPUT_OPTIONS 53 | * SOURCE 54 | */ 55 | typedef enum _xml_elem_verbosity { 56 | xml_elem_no_white_space, /* compact xml with no white space */ 57 | xml_elem_newlines_only, /* add newlines for enhanced readability */ 58 | xml_elem_pretty /* add newlines and indent accordind to depth */ 59 | } XML_ELEM_VERBOSITY; 60 | /******/ 61 | 62 | 63 | /****d* enum/XML_ELEM_ESCAPING 64 | * NAME 65 | * XML_ELEM_ESCAPING 66 | * NOTES 67 | * xml escaping options for generated xml 68 | * SEE ALSO 69 | * XML_ELEM_OUTPUT_OPTIONS 70 | * SOURCE 71 | */ 72 | typedef enum _xml_elem_escaping { 73 | xml_elem_no_escaping = 0x000, 74 | xml_elem_markup_escaping = 0x002, /* entity escape xml special chars */ 75 | xml_elem_non_ascii_escaping = 0x008, /* entity escape chars above 127 */ 76 | xml_elem_non_print_escaping = 0x010, /* entity escape non print (illegal) chars */ 77 | xml_elem_cdata_escaping = 0x020, /* wrap in cdata section */ 78 | } XML_ELEM_ESCAPING; 79 | /******/ 80 | 81 | 82 | /****s* struct/XML_ELEM_OUTPUT_OPTIONS 83 | * NAME 84 | * XML_ELEM_OUTPUT_OPTIONS 85 | * NOTES 86 | * defines various output options 87 | * SOURCE 88 | */ 89 | typedef struct _xml_output_options { 90 | XML_ELEM_VERBOSITY verbosity; /* length/verbosity of xml */ 91 | XML_ELEM_ESCAPING escaping; /* how to escape special chars */ 92 | const char* encoding; /* " ?> */ 93 | } STRUCT_XML_ELEM_OUTPUT_OPTIONS, *XML_ELEM_OUTPUT_OPTIONS; 94 | /******/ 95 | 96 | /****s* struct/XML_ELEM_INPUT_OPTIONS 97 | * NAME 98 | * XML_ELEM_INPUT_OPTIONS 99 | * NOTES 100 | * defines various input options 101 | * SOURCE 102 | */ 103 | typedef struct _xml_input_options { 104 | ENCODING_ID encoding; /* which encoding to use. */ 105 | } STRUCT_XML_ELEM_INPUT_OPTIONS, *XML_ELEM_INPUT_OPTIONS; 106 | /******/ 107 | 108 | /****s* struct/XML_ELEM_ERROR 109 | * NAME 110 | * XML_ELEM_ERROR 111 | * NOTES 112 | * defines an xml parser error 113 | * SOURCE 114 | */ 115 | typedef struct _xml_elem_error { 116 | int parser_code; 117 | const char* parser_error; 118 | long line; 119 | long column; 120 | long byte_index; 121 | } STRUCT_XML_ELEM_ERROR, *XML_ELEM_ERROR; 122 | /******/ 123 | 124 | 125 | /*-************************ 126 | * begin xml element stuff * 127 | **************************/ 128 | 129 | /****s* struct/xml_elem_attr 130 | * NAME 131 | * xml_elem_attr 132 | * NOTES 133 | * representation of an xml attribute, foo="bar" 134 | * SOURCE 135 | */ 136 | typedef struct _xml_element_attr { 137 | char* key; /* attribute key */ 138 | char* val; /* attribute value */ 139 | } xml_element_attr; 140 | /******/ 141 | 142 | /****s* struct/xml_elem_attr 143 | * NAME 144 | * xml_elem_attr 145 | * NOTES 146 | * representation of an xml element, eg 147 | * SOURCE 148 | */ 149 | typedef struct _xml_element { 150 | const char* name; /* element identifier */ 151 | simplestring text; /* text contained between element begin/end pairs */ 152 | struct _xml_element* parent; /* element's parent */ 153 | 154 | queue attrs; /* attribute list */ 155 | queue children; /* child element list */ 156 | } xml_element; 157 | /******/ 158 | 159 | void xml_elem_free(xml_element* root); 160 | void xml_elem_free_non_recurse(xml_element* root); 161 | xml_element* xml_elem_new(void); 162 | char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len); 163 | void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options); 164 | xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error); 165 | 166 | /*-********************** 167 | * end xml element stuff * 168 | ************************/ 169 | 170 | /*-********************** 171 | * Begin xml_element API * 172 | ************************/ 173 | 174 | /****d* VALUE/XMLRPC_MACROS 175 | * NAME 176 | * Some Helpful Macros 177 | * NOTES 178 | * Some macros for making life easier. Should be self-explanatory. 179 | * SEE ALSO 180 | * XMLRPC_AddValueToVector () 181 | * XMLRPC_VectorGetValueWithID_Case () 182 | * XMLRPC_VALUE 183 | * SOURCE 184 | */ 185 | #define xml_elem_next_element(el) ((el) ? (xml_element *)Q_Next(&el->children) : NULL) 186 | #define xml_elem_head_element(el) ((el) ? (xml_element *)Q_Head(&el->children) : NULL) 187 | #define xml_elem_next_attr(el) ((el) ? (xml_element_attr *)Q_Next(&el->attrs) : NULL) 188 | #define xml_elem_head_attr(el) ((el) ? (xml_element_attr *)Q_Head(&el->attrs) : NULL) 189 | #define xml_elem_get_name(el) (char *)((el) ? el->name : NULL) 190 | #define xml_elem_get_val(el) (char *)((el) ? el->text.str : NULL) 191 | /******/ 192 | 193 | 194 | /*-******************** 195 | * End xml_element API * 196 | **********************/ 197 | 198 | #ifdef __cplusplus 199 | } 200 | #endif 201 | 202 | #endif /* __XML_ELEMENT_H__ */ 203 | -------------------------------------------------------------------------------- /libxmlrpc/simplestring.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #include 34 | 35 | 36 | #define SIMPLESTRING_INCR 32 37 | 38 | /****h* ABOUT/simplestring 39 | * NAME 40 | * simplestring 41 | * AUTHOR 42 | * Dan Libby, aka danda (dan@libby.com) 43 | * CREATION DATE 44 | * 06/2000 45 | * HISTORY 46 | * $Log$ 47 | * Revision 1.3 2002/08/22 01:25:50 sniper 48 | * kill some compile warnings 49 | * 50 | * Revision 1.2 2002/07/05 04:43:53 danda 51 | * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 52 | * 53 | * Revision 1.4 2002/02/13 20:58:50 danda 54 | * patch to make source more windows friendly, contributed by Jeff Lawson 55 | * 56 | * Revision 1.3 2001/09/29 21:58:05 danda 57 | * adding cvs log to history section 58 | * 59 | * 10/15/2000 -- danda -- adding robodoc documentation 60 | * PORTABILITY 61 | * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just 62 | * about anything with minor mods. 63 | * NOTES 64 | * This code was written primarily for xmlrpc, but has found some other uses. 65 | * 66 | * simplestring is, as the name implies, a simple API for dealing with C strings. 67 | * Why would I write yet another string API? Because I couldn't find any that were 68 | * a) free / GPL, b) simple/lightweight, c) fast, not doing unnecessary strlens all 69 | * over the place. So. It is simple, and it seems to work, and it is pretty fast. 70 | * 71 | * Oh, and it is also binary safe, ie it can handle strings with embedded NULLs, 72 | * so long as the real length is passed in. 73 | * 74 | * And the masses rejoiced. 75 | * 76 | * BUGS 77 | * there must be some. 78 | ******/ 79 | 80 | #include 81 | #include 82 | #include 83 | #include "simplestring.h" 84 | 85 | #define my_free(thing) if(thing) {efree(thing); thing = 0;} 86 | 87 | /*----------------------** 88 | * Begin String Functions * 89 | *-----------------------*/ 90 | 91 | /****f* FUNC/simplestring_init 92 | * NAME 93 | * simplestring_init 94 | * SYNOPSIS 95 | * void simplestring_init(simplestring* string) 96 | * FUNCTION 97 | * initialize string 98 | * INPUTS 99 | * string - pointer to a simplestring struct that will be initialized 100 | * RESULT 101 | * void 102 | * NOTES 103 | * SEE ALSO 104 | * simplestring_free () 105 | * simplestring_clear () 106 | * SOURCE 107 | */ 108 | void simplestring_init(simplestring* string) { 109 | memset(string, 0, sizeof(simplestring)); 110 | } 111 | /******/ 112 | 113 | static void simplestring_init_str(simplestring* string) { 114 | string->str = (char*)emalloc(SIMPLESTRING_INCR); 115 | if(string->str) { 116 | string->str[0] = 0; 117 | string->len = 0; 118 | string->size = SIMPLESTRING_INCR; 119 | } 120 | else { 121 | string->size = 0; 122 | } 123 | } 124 | 125 | /****f* FUNC/simplestring_clear 126 | * NAME 127 | * simplestring_clear 128 | * SYNOPSIS 129 | * void simplestring_clear(simplestring* string) 130 | * FUNCTION 131 | * clears contents of a string 132 | * INPUTS 133 | * string - the string value to clear 134 | * RESULT 135 | * void 136 | * NOTES 137 | * This function is very fast as it does not de-allocate any memory. 138 | * SEE ALSO 139 | * 140 | * SOURCE 141 | */ 142 | void simplestring_clear(simplestring* string) { 143 | if(string->str) { 144 | string->str[0] = 0; 145 | } 146 | string->len = 0; 147 | } 148 | /******/ 149 | 150 | /****f* FUNC/simplestring_free 151 | * NAME 152 | * simplestring_free 153 | * SYNOPSIS 154 | * void simplestring_free(simplestring* string) 155 | * FUNCTION 156 | * frees contents of a string, if any. Does *not* free the simplestring struct itself. 157 | * INPUTS 158 | * string - value containing string to be free'd 159 | * RESULT 160 | * void 161 | * NOTES 162 | * caller is responsible for allocating and freeing simplestring* struct itself. 163 | * SEE ALSO 164 | * simplestring_init () 165 | * SOURCE 166 | */ 167 | void simplestring_free(simplestring* string) { 168 | if(string && string->str) { 169 | my_free(string->str); 170 | string->len = 0; 171 | } 172 | } 173 | /******/ 174 | 175 | #ifndef SIZE_MAX 176 | #define SIZE_MAX ((size_t)-1) 177 | #endif 178 | /****f* FUNC/simplestring_addn 179 | * NAME 180 | * simplestring_addn 181 | * SYNOPSIS 182 | * void simplestring_addn(simplestring* string, const char* add, int add_len) 183 | * FUNCTION 184 | * copies n characters from source to target string 185 | * INPUTS 186 | * target - target string 187 | * source - source string 188 | * add_len - number of characters to copy 189 | * RESULT 190 | * void 191 | * NOTES 192 | * SEE ALSO 193 | * simplestring_add () 194 | * SOURCE 195 | */ 196 | void simplestring_addn(simplestring* target, const char* source, size_t add_len) { 197 | size_t newsize = target->size, incr = 0; 198 | if(target && source) { 199 | if(!target->str) { 200 | simplestring_init_str(target); 201 | } 202 | 203 | if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) { 204 | /* check for overflows, if there's a potential overflow do nothing */ 205 | return; 206 | } 207 | 208 | if(target->len + add_len + 1 > target->size) { 209 | /* newsize is current length + new length */ 210 | newsize = target->len + add_len + 1; 211 | incr = target->size * 2; 212 | 213 | /* align to SIMPLESTRING_INCR increments */ 214 | if (incr) { 215 | newsize = newsize - (newsize % incr) + incr; 216 | } 217 | if(newsize < (target->len + add_len + 1)) { 218 | /* some kind of overflow happened */ 219 | return; 220 | } 221 | target->str = (char*)erealloc(target->str, newsize); 222 | 223 | target->size = target->str ? newsize : 0; 224 | } 225 | 226 | if(target->str) { 227 | if(add_len) { 228 | memcpy(target->str + target->len, source, add_len); 229 | } 230 | target->len += add_len; 231 | target->str[target->len] = 0; /* null terminate */ 232 | } 233 | } 234 | } 235 | /******/ 236 | 237 | /****f* FUNC/simplestring_add 238 | * NAME 239 | * simplestring_add 240 | * SYNOPSIS 241 | * void simplestring_add(simplestring* string, const char* add) 242 | * FUNCTION 243 | * appends a string of unknown length from source to target 244 | * INPUTS 245 | * target - the target string to append to 246 | * source - the source string of unknown length 247 | * RESULT 248 | * void 249 | * NOTES 250 | * SEE ALSO 251 | * simplestring_addn () 252 | * SOURCE 253 | */ 254 | void simplestring_add(simplestring* target, const char* source) { 255 | if(target && source) { 256 | simplestring_addn(target, source, strlen(source)); 257 | } 258 | } 259 | /******/ 260 | 261 | 262 | /*---------------------- 263 | * End String Functions * 264 | *--------------------**/ 265 | -------------------------------------------------------------------------------- /libxmlrpc/xml_to_dandarpc.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #include 34 | #include 35 | #include "xml_to_dandarpc.h" 36 | #include "base64.h" 37 | 38 | /* list of tokens used in vocab */ 39 | #define ELEM_METHODCALL "methodCall" 40 | #define ELEM_METHODNAME "methodName" 41 | #define ELEM_METHODRESPONSE "methodResponse" 42 | #define ELEM_ROOT "simpleRPC" 43 | 44 | #define ATTR_ARRAY "array" 45 | #define ATTR_BASE64 "base64" 46 | #define ATTR_BOOLEAN "boolean" 47 | #define ATTR_DATETIME "dateTime.iso8601" 48 | #define ATTR_DOUBLE "double" 49 | #define ATTR_ID "id" 50 | #define ATTR_INT "int" 51 | #define ATTR_MIXED "mixed" 52 | #define ATTR_SCALAR "scalar" 53 | #define ATTR_STRING "string" 54 | #define ATTR_STRUCT "struct" 55 | #define ATTR_TYPE "type" 56 | #define ATTR_VECTOR "vector" 57 | #define ATTR_VERSION "version" 58 | 59 | #define VAL_VERSION_0_9 "0.9" 60 | 61 | 62 | XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xCurrent, xml_element* el) { 63 | if(!xCurrent) { 64 | xCurrent = XMLRPC_CreateValueEmpty(); 65 | } 66 | 67 | if(el->name) { 68 | const char* id = NULL; 69 | const char* type = NULL; 70 | xml_element_attr* attr_iter = Q_Head(&el->attrs); 71 | 72 | while(attr_iter) { 73 | if(!strcmp(attr_iter->key, ATTR_ID)) { 74 | id = attr_iter->val; 75 | } 76 | if(!strcmp(attr_iter->key, ATTR_TYPE)) { 77 | type = attr_iter->val; 78 | } 79 | attr_iter = Q_Next(&el->attrs); 80 | } 81 | 82 | if(id) { 83 | XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact); 84 | } 85 | 86 | if(!strcmp(el->name, ATTR_SCALAR)) { 87 | if(!type || !strcmp(type, ATTR_STRING)) { 88 | XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len); 89 | } 90 | else if(!strcmp(type, ATTR_INT)) { 91 | XMLRPC_SetValueInt(xCurrent, atoi(el->text.str)); 92 | } 93 | else if(!strcmp(type, ATTR_BOOLEAN)) { 94 | XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str)); 95 | } 96 | else if(!strcmp(type, ATTR_DOUBLE)) { 97 | XMLRPC_SetValueDouble(xCurrent, atof(el->text.str)); 98 | } 99 | else if(!strcmp(type, ATTR_DATETIME)) { 100 | XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str); 101 | } 102 | else if(!strcmp(type, ATTR_BASE64)) { 103 | struct buffer_st buf; 104 | base64_decode_xmlrpc(&buf, el->text.str, el->text.len); 105 | XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset); 106 | buffer_delete(&buf); 107 | } 108 | } 109 | else if(!strcmp(el->name, ATTR_VECTOR)) { 110 | xml_element* iter = (xml_element*)Q_Head(&el->children); 111 | 112 | if(!type || !strcmp(type, ATTR_MIXED)) { 113 | XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed); 114 | } 115 | else if(!strcmp(type, ATTR_ARRAY)) { 116 | XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array); 117 | } 118 | else if(!strcmp(type, ATTR_STRUCT)) { 119 | XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct); 120 | } 121 | while( iter ) { 122 | XMLRPC_VALUE xNext = XMLRPC_CreateValueEmpty(); 123 | xml_element_to_DANDARPC_REQUEST_worker(request, xNext, iter); 124 | XMLRPC_AddValueToVector(xCurrent, xNext); 125 | iter = (xml_element*)Q_Next(&el->children); 126 | } 127 | } 128 | else { 129 | xml_element* iter = (xml_element*)Q_Head(&el->children); 130 | while( iter ) { 131 | xml_element_to_DANDARPC_REQUEST_worker(request, xCurrent, iter); 132 | iter = (xml_element*)Q_Next(&el->children); 133 | } 134 | 135 | if(!strcmp(el->name, ELEM_METHODCALL)) { 136 | if(request) { 137 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); 138 | } 139 | } 140 | else if(!strcmp(el->name, ELEM_METHODRESPONSE)) { 141 | if(request) { 142 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); 143 | } 144 | } 145 | else if(!strcmp(el->name, ELEM_METHODNAME)) { 146 | if(request) { 147 | XMLRPC_RequestSetMethodName(request, el->text.str); 148 | } 149 | } 150 | } 151 | } 152 | return xCurrent; 153 | } 154 | 155 | XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el) 156 | { 157 | return xml_element_to_DANDARPC_REQUEST_worker(NULL, NULL, el); 158 | } 159 | 160 | XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el) 161 | { 162 | if(request) { 163 | return XMLRPC_RequestSetData(request, xml_element_to_DANDARPC_REQUEST_worker(request, NULL, el)); 164 | } 165 | return NULL; 166 | } 167 | 168 | xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) { 169 | #define BUF_SIZE 512 170 | xml_element* root = NULL; 171 | if(node) { 172 | char buf[BUF_SIZE]; 173 | const char* id = XMLRPC_GetValueID(node); 174 | XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); 175 | XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request); 176 | int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space); 177 | xml_element* elem_val = xml_elem_new(); 178 | const char* pAttrType = NULL; 179 | 180 | xml_element_attr* attr_type = bNoAddType ? NULL : emalloc(sizeof(xml_element_attr)); 181 | 182 | if(attr_type) { 183 | attr_type->key = estrdup(ATTR_TYPE); 184 | attr_type->val = 0; 185 | Q_PushTail(&elem_val->attrs, attr_type); 186 | } 187 | 188 | elem_val->name = (type == xmlrpc_vector) ? estrdup(ATTR_VECTOR) : estrdup(ATTR_SCALAR); 189 | 190 | if(id && *id) { 191 | xml_element_attr* attr_id = emalloc(sizeof(xml_element_attr)); 192 | if(attr_id) { 193 | attr_id->key = estrdup(ATTR_ID); 194 | attr_id->val = estrdup(id); 195 | Q_PushTail(&elem_val->attrs, attr_id); 196 | } 197 | } 198 | 199 | switch(type) { 200 | case xmlrpc_string: 201 | pAttrType = ATTR_STRING; 202 | simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); 203 | break; 204 | case xmlrpc_int: 205 | pAttrType = ATTR_INT; 206 | snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); 207 | simplestring_add(&elem_val->text, buf); 208 | break; 209 | case xmlrpc_boolean: 210 | pAttrType = ATTR_BOOLEAN; 211 | snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); 212 | simplestring_add(&elem_val->text, buf); 213 | break; 214 | case xmlrpc_double: 215 | pAttrType = ATTR_DOUBLE; 216 | snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); 217 | simplestring_add(&elem_val->text, buf); 218 | break; 219 | case xmlrpc_datetime: 220 | pAttrType = ATTR_DATETIME; 221 | simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); 222 | break; 223 | case xmlrpc_base64: 224 | { 225 | struct buffer_st buf; 226 | pAttrType = ATTR_BASE64; 227 | base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); 228 | simplestring_addn(&elem_val->text, buf.data, buf.offset ); 229 | buffer_delete(&buf); 230 | } 231 | break; 232 | case xmlrpc_vector: 233 | { 234 | XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); 235 | XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); 236 | 237 | switch(my_type) { 238 | case xmlrpc_vector_array: 239 | pAttrType = ATTR_ARRAY; 240 | break; 241 | case xmlrpc_vector_mixed: 242 | pAttrType = ATTR_MIXED; 243 | break; 244 | case xmlrpc_vector_struct: 245 | pAttrType = ATTR_STRUCT; 246 | break; 247 | default: 248 | break; 249 | } 250 | 251 | /* recurse through sub-elements */ 252 | while( xIter ) { 253 | xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter); 254 | if(next_el) { 255 | Q_PushTail(&elem_val->children, next_el); 256 | } 257 | xIter = XMLRPC_VectorNext(node); 258 | } 259 | } 260 | break; 261 | default: 262 | break; 263 | } 264 | if(pAttrType && attr_type && !bNoAddType) { 265 | attr_type->val = estrdup(pAttrType); 266 | } 267 | root = elem_val; 268 | } 269 | return root; 270 | } 271 | 272 | xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node) { 273 | return DANDARPC_to_xml_element_worker(NULL, node); 274 | } 275 | 276 | xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { 277 | xml_element* wrapper = NULL; 278 | xml_element* root = NULL; 279 | if(request) { 280 | XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); 281 | const char* pStr = NULL; 282 | xml_element_attr* version = emalloc(sizeof(xml_element_attr)); 283 | version->key = estrdup(ATTR_VERSION); 284 | version->val = estrdup(VAL_VERSION_0_9); 285 | 286 | wrapper = xml_elem_new(); 287 | 288 | if(request_type == xmlrpc_request_response) { 289 | pStr = ELEM_METHODRESPONSE; 290 | } 291 | else if(request_type == xmlrpc_request_call) { 292 | pStr = ELEM_METHODCALL; 293 | } 294 | if(pStr) { 295 | wrapper->name = estrdup(pStr); 296 | } 297 | 298 | root = xml_elem_new(); 299 | root->name = estrdup(ELEM_ROOT); 300 | Q_PushTail(&root->attrs, version); 301 | Q_PushTail(&root->children, wrapper); 302 | 303 | pStr = XMLRPC_RequestGetMethodName(request); 304 | 305 | if(pStr) { 306 | xml_element* method = xml_elem_new(); 307 | method->name = estrdup(ELEM_METHODNAME); 308 | simplestring_add(&method->text, pStr); 309 | Q_PushTail(&wrapper->children, method); 310 | } 311 | Q_PushTail(&wrapper->children, 312 | DANDARPC_to_xml_element_worker(request, XMLRPC_RequestGetData(request))); 313 | } 314 | return root; 315 | } 316 | -------------------------------------------------------------------------------- /libxmlrpc/system_methods.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2001 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | /****h* ABOUT/system_methods 35 | * AUTHOR 36 | * Dan Libby, aka danda (dan@libby.com) 37 | * HISTORY 38 | * $Log$ 39 | * Revision 1.7 2001/09/29 21:58:05 danda 40 | * adding cvs log to history section 41 | * 42 | * 4/28/2001 -- danda -- adding system.multicall and separating out system methods. 43 | * TODO 44 | * NOTES 45 | *******/ 46 | 47 | 48 | #include "queue.h" 49 | #include "xmlrpc.h" 50 | #include "xmlrpc_private.h" 51 | #include "xmlrpc_introspection_private.h" 52 | #include "system_methods_private.h" 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | static const char* xsm_introspection_xml = 59 | "" 60 | 61 | "" 62 | "" 63 | 64 | "" 65 | "value identifier" 66 | "value's xmlrpc or user-defined type" 67 | "value's textual description " 68 | "true if value is optional, else it is required " 69 | "a child of this element. n/a for scalar types " 70 | "" 71 | 72 | "" 73 | "" 74 | "" 75 | 76 | "" 77 | "" 78 | "" 79 | 80 | 81 | "" 82 | 83 | "" 84 | 85 | "" 86 | "" 87 | "Dan Libby" 88 | "fully describes the methods and types implemented by this XML-RPC server." 89 | "1.1" 90 | "" 91 | "" 92 | "" 93 | "" 94 | "a valid method name" 95 | "" 96 | "" 97 | "" 98 | "" 99 | "" 100 | "" 101 | "method name" 102 | "method version" 103 | "method author" 104 | "method purpose" 105 | "" 106 | "" 107 | "parameter list" 108 | "return value list" 109 | "" 110 | "" 111 | "list of known bugs" 112 | "list of possible errors and error codes" 113 | "list of examples" 114 | "list of modifications" 115 | "list of notes" 116 | "see also. list of related methods" 117 | "list of unimplemented features" 118 | "" 119 | "" 120 | "" 121 | "a type description" 122 | "" 123 | "" 124 | "" 125 | "" 126 | "" 127 | "" 128 | "" 129 | "" 130 | "" 131 | "" 132 | "" 133 | "" 134 | "" 135 | "" 136 | "" 137 | "" 138 | 139 | "" 140 | "" 141 | "Dan Libby" 142 | "enumerates the methods implemented by this XML-RPC server." 143 | "1.0" 144 | "" 145 | "" 146 | "" 147 | "" 148 | "name of a method implemented by the server." 149 | "" 150 | "" 151 | "" 152 | "" 153 | "" 154 | "" 155 | "" 156 | "" 157 | "" 158 | "" 159 | "" 160 | "" 161 | "" 162 | "" 163 | "" 164 | 165 | "" 166 | "" 167 | "Dan Libby" 168 | "provides documentation string for a single method" 169 | "1.0" 170 | "" 171 | "" 172 | "" 173 | "name of the method for which documentation is desired" 174 | "" 175 | "" 176 | "help text if defined for the method passed, otherwise an empty string" 177 | "" 178 | "" 179 | "" 180 | "" 181 | "" 182 | "" 183 | "" 184 | "" 185 | "" 186 | "" 187 | "" 188 | "" 189 | "" 190 | "" 191 | 192 | "" 193 | "" 194 | "Dan Libby" 195 | "provides 1 or more signatures for a single method" 196 | "1.0" 197 | "" 198 | "" 199 | "" 200 | "name of the method for which documentation is desired" 201 | "" 202 | "" 203 | "" 204 | "" 205 | "a string indicating the xmlrpc type of a value. one of: string, int, double, base64, datetime, array, struct" 206 | "" 207 | "" 208 | "" 209 | "" 210 | "" 211 | "" 212 | "" 213 | "" 214 | "" 215 | "" 216 | "" 217 | "" 218 | "" 219 | "" 220 | "" 221 | "" 222 | 223 | "" 224 | "" 225 | "Dan Libby" 226 | "executes multiple methods in sequence and returns the results" 227 | "1.0" 228 | "" 229 | "" 230 | "" 231 | "" 232 | "" 233 | "" 234 | "" 235 | "" 236 | "" 237 | "" 238 | "" 239 | "" 240 | "" 241 | "" 242 | "" 243 | "" 244 | "" 245 | "" 246 | "" 247 | "" 248 | "" 249 | "" 250 | "" 251 | "" 252 | "" 253 | "" 254 | "" 255 | "" 256 | 257 | "" 258 | "" 259 | "Dan Libby" 260 | "returns a list of capabilities supported by this server" 261 | "1.0" 262 | "spec url: http://groups.yahoo.com/group/xml-rpc/message/2897" 263 | "" 264 | "" 265 | "" 266 | "" 267 | "" 268 | "www address of the specification defining this capability" 269 | "version of the spec that this server's implementation conforms to" 270 | "" 271 | "" 272 | "" 273 | "" 274 | "" 275 | "" 276 | "" 277 | "" 278 | "" 279 | "" 280 | "" 281 | "" 282 | "" 283 | "" 284 | "" 285 | "" 286 | 287 | "" 288 | ""; 289 | 290 | 291 | /* forward declarations for static (non public, non api) funcs */ 292 | static XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 293 | static XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 294 | 295 | /*-******************* 296 | * System Methods API * 297 | *********************/ 298 | 299 | static void xsm_lazy_doc_methods_cb(XMLRPC_SERVER server, void* userData) { 300 | XMLRPC_VALUE xDesc = XMLRPC_IntrospectionCreateDescription(xsm_introspection_xml, NULL); 301 | XMLRPC_ServerAddIntrospectionData(server, xDesc); 302 | XMLRPC_CleanupValue(xDesc); 303 | } 304 | 305 | void xsm_register(XMLRPC_SERVER server) { 306 | xi_register_system_methods(server); 307 | 308 | XMLRPC_ServerRegisterMethod(server, xsm_token_system_multicall, xsm_system_multicall_cb); 309 | XMLRPC_ServerRegisterMethod(server, xsm_token_system_get_capabilities, xsm_system_get_capabilities_cb); 310 | 311 | /* callback for documentation generation should it be requested */ 312 | XMLRPC_ServerRegisterIntrospectionCallback(server, xsm_lazy_doc_methods_cb); 313 | } 314 | 315 | XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 316 | XMLRPC_VALUE xArray = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); 317 | XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_array); 318 | 319 | if (xArray) { 320 | XMLRPC_VALUE xMethodIter = XMLRPC_VectorRewind(xArray); 321 | 322 | while (xMethodIter) { 323 | XMLRPC_REQUEST request = XMLRPC_RequestNew(); 324 | if(request) { 325 | const char* methodName = XMLRPC_VectorGetStringWithID(xMethodIter, "methodName"); 326 | XMLRPC_VALUE params = XMLRPC_VectorGetValueWithID(xMethodIter, "params"); 327 | 328 | if(methodName && params) { 329 | XMLRPC_VALUE xRandomArray = XMLRPC_CreateVector(0, xmlrpc_vector_array); 330 | XMLRPC_RequestSetMethodName(request, methodName); 331 | XMLRPC_RequestSetData(request, params); 332 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); 333 | 334 | XMLRPC_AddValueToVector(xRandomArray, 335 | XMLRPC_ServerCallMethod(server, request, userData)); 336 | 337 | XMLRPC_AddValueToVector(xReturn, xRandomArray); 338 | } 339 | XMLRPC_RequestFree(request, 1); 340 | } 341 | xMethodIter = XMLRPC_VectorNext(xArray); 342 | } 343 | } 344 | return xReturn; 345 | } 346 | 347 | 348 | XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 349 | XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_struct); 350 | XMLRPC_VALUE xFaults = XMLRPC_CreateVector("faults_interop", xmlrpc_vector_struct); 351 | XMLRPC_VALUE xIntro = XMLRPC_CreateVector("introspection", xmlrpc_vector_struct); 352 | 353 | /* support for fault spec */ 354 | XMLRPC_VectorAppendString(xFaults, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php", 0); 355 | XMLRPC_VectorAppendInt(xFaults, "specVersion", 20010516); 356 | 357 | /* support for introspection spec */ 358 | XMLRPC_VectorAppendString(xIntro, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.introspection.php", 0); 359 | XMLRPC_VectorAppendInt(xIntro, "specVersion", 20010516); 360 | 361 | XMLRPC_AddValuesToVector(xReturn, 362 | xFaults, 363 | xIntro, 364 | NULL); 365 | 366 | return xReturn; 367 | 368 | } 369 | 370 | /*-*********************** 371 | * End System Methods API * 372 | *************************/ 373 | -------------------------------------------------------------------------------- /libxmlrpc/xml_to_xmlrpc.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | #include "php.h" 35 | #include "main/snprintf.h" 36 | #include 37 | #include 38 | #include "xml_to_xmlrpc.h" 39 | #include "base64.h" 40 | 41 | /* list of tokens used in vocab */ 42 | #define ELEM_ARRAY "array" 43 | #define ELEM_BASE64 "base64" 44 | #define ELEM_BOOLEAN "boolean" 45 | #define ELEM_DATA "data" 46 | #define ELEM_DATETIME "dateTime.iso8601" 47 | #define ELEM_DOUBLE "double" 48 | #define ELEM_FAULT "fault" 49 | #define ELEM_FAULTCODE "faultCode" 50 | #define ELEM_FAULTSTRING "faultString" 51 | #define ELEM_I4 "i4" 52 | #define ELEM_INT "int" 53 | #define ELEM_MEMBER "member" 54 | #define ELEM_METHODCALL "methodCall" 55 | #define ELEM_METHODNAME "methodName" 56 | #define ELEM_METHODRESPONSE "methodResponse" 57 | #define ELEM_NAME "name" 58 | #define ELEM_PARAM "param" 59 | #define ELEM_PARAMS "params" 60 | #define ELEM_STRING "string" 61 | #define ELEM_STRUCT "struct" 62 | #define ELEM_VALUE "value" 63 | 64 | 65 | XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE parent_vector, XMLRPC_VALUE current_val, xml_element* el) { 66 | if (!current_val) { 67 | /* This should only be the case for the first element */ 68 | current_val = XMLRPC_CreateValueEmpty(); 69 | } 70 | 71 | if (el->name) { 72 | 73 | /* first, deal with the crazy/stupid fault format */ 74 | if (!strcmp(el->name, ELEM_FAULT)) { 75 | xml_element* fault_value = (xml_element*)Q_Head(&el->children); 76 | XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); 77 | 78 | if(fault_value) { 79 | xml_element* fault_struct = (xml_element*)Q_Head(&fault_value->children); 80 | if(fault_struct) { 81 | xml_element* iter = (xml_element*)Q_Head(&fault_struct->children); 82 | 83 | while (iter) { 84 | XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); 85 | xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); 86 | XMLRPC_AddValueToVector(current_val, xNextVal); 87 | iter = (xml_element*)Q_Next(&fault_struct->children); 88 | } 89 | } 90 | } 91 | } 92 | else if (!strcmp(el->name, ELEM_DATA) /* should be ELEM_ARRAY, but there is an extra level. weird */ 93 | || (!strcmp(el->name, ELEM_PARAMS) && 94 | (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call)) ) { /* this "PARAMS" concept is silly. dave?! */ 95 | xml_element* iter = (xml_element*)Q_Head(&el->children); 96 | XMLRPC_SetIsVector(current_val, xmlrpc_vector_array); 97 | 98 | while (iter) { 99 | XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); 100 | xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); 101 | XMLRPC_AddValueToVector(current_val, xNextVal); 102 | iter = (xml_element*)Q_Next(&el->children); 103 | } 104 | } 105 | else if (!strcmp(el->name, ELEM_STRUCT)) { 106 | xml_element* iter = (xml_element*)Q_Head(&el->children); 107 | XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); 108 | 109 | while ( iter ) { 110 | XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); 111 | xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); 112 | XMLRPC_AddValueToVector(current_val, xNextVal); 113 | iter = (xml_element*)Q_Next(&el->children); 114 | } 115 | } 116 | else if (!strcmp(el->name, ELEM_STRING) || 117 | (!strcmp(el->name, ELEM_VALUE) && Q_Size(&el->children) == 0)) { 118 | XMLRPC_SetValueString(current_val, el->text.str, el->text.len); 119 | } 120 | else if (!strcmp(el->name, ELEM_NAME)) { 121 | XMLRPC_SetValueID_Case(current_val, el->text.str, 0, xmlrpc_case_exact); 122 | } 123 | else if (!strcmp(el->name, ELEM_INT) || !strcmp(el->name, ELEM_I4)) { 124 | XMLRPC_SetValueInt(current_val, atoi(el->text.str)); 125 | } 126 | else if (!strcmp(el->name, ELEM_BOOLEAN)) { 127 | XMLRPC_SetValueBoolean(current_val, atoi(el->text.str)); 128 | } 129 | else if (!strcmp(el->name, ELEM_DOUBLE)) { 130 | XMLRPC_SetValueDouble(current_val, atof(el->text.str)); 131 | } 132 | else if (!strcmp(el->name, ELEM_DATETIME)) { 133 | XMLRPC_SetValueDateTime_ISO8601(current_val, el->text.str); 134 | } 135 | else if (!strcmp(el->name, ELEM_BASE64)) { 136 | struct buffer_st buf; 137 | base64_decode_xmlrpc(&buf, el->text.str, el->text.len); 138 | XMLRPC_SetValueBase64(current_val, buf.data, buf.offset); 139 | buffer_delete(&buf); 140 | } 141 | else { 142 | xml_element* iter; 143 | 144 | if (!strcmp(el->name, ELEM_METHODCALL)) { 145 | if (request) { 146 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); 147 | } 148 | } 149 | else if (!strcmp(el->name, ELEM_METHODRESPONSE)) { 150 | if (request) { 151 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); 152 | } 153 | } 154 | else if (!strcmp(el->name, ELEM_METHODNAME)) { 155 | if (request) { 156 | XMLRPC_RequestSetMethodName(request, el->text.str); 157 | } 158 | } 159 | 160 | iter = (xml_element*)Q_Head(&el->children); 161 | while ( iter ) { 162 | xml_element_to_XMLRPC_REQUEST_worker(request, parent_vector, 163 | current_val, iter); 164 | iter = (xml_element*)Q_Next(&el->children); 165 | } 166 | } 167 | } 168 | return current_val; 169 | } 170 | 171 | XMLRPC_VALUE xml_element_to_XMLRPC_VALUE(xml_element* el) 172 | { 173 | return xml_element_to_XMLRPC_REQUEST_worker(NULL, NULL, NULL, el); 174 | } 175 | 176 | XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST(XMLRPC_REQUEST request, xml_element* el) 177 | { 178 | if (request) { 179 | return XMLRPC_RequestSetData(request, xml_element_to_XMLRPC_REQUEST_worker(request, NULL, NULL, el)); 180 | } 181 | return NULL; 182 | } 183 | 184 | xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VALUE node, 185 | XMLRPC_REQUEST_TYPE request_type, int depth) { 186 | #define BUF_SIZE 512 187 | xml_element* root = NULL; 188 | if (node) { 189 | char buf[BUF_SIZE]; 190 | XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); 191 | XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(node); 192 | xml_element* elem_val = xml_elem_new(); 193 | 194 | /* special case for when root element is not an array */ 195 | if (depth == 0 && 196 | !(type == xmlrpc_vector && 197 | vtype == xmlrpc_vector_array && 198 | request_type == xmlrpc_request_call) ) { 199 | int bIsFault = (vtype == xmlrpc_vector_struct && XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)); 200 | 201 | xml_element* next_el = XMLRPC_to_xml_element_worker(NULL, node, request_type, depth + 1); 202 | if (next_el) { 203 | Q_PushTail(&elem_val->children, next_el); 204 | } 205 | elem_val->name = estrdup(bIsFault ? ELEM_FAULT : ELEM_PARAMS); 206 | } 207 | else { 208 | switch (type) { 209 | case xmlrpc_empty: /* treat null value as empty string in xmlrpc. */ 210 | case xmlrpc_string: 211 | elem_val->name = estrdup(ELEM_STRING); 212 | simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); 213 | break; 214 | case xmlrpc_int: 215 | elem_val->name = estrdup(ELEM_INT); 216 | snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); 217 | simplestring_add(&elem_val->text, buf); 218 | break; 219 | case xmlrpc_boolean: 220 | elem_val->name = estrdup(ELEM_BOOLEAN); 221 | snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); 222 | simplestring_add(&elem_val->text, buf); 223 | break; 224 | case xmlrpc_double: 225 | { 226 | elem_val->name = estrdup(ELEM_DOUBLE); 227 | ap_php_snprintf(buf, BUF_SIZE, "%.*G", (int) EG(precision), XMLRPC_GetValueDouble(node)); 228 | simplestring_add(&elem_val->text, buf); 229 | } 230 | break; 231 | case xmlrpc_datetime: 232 | elem_val->name = estrdup(ELEM_DATETIME); 233 | simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); 234 | break; 235 | case xmlrpc_base64: 236 | { 237 | struct buffer_st buf; 238 | elem_val->name = estrdup(ELEM_BASE64); 239 | base64_encode_xmlrpc(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); 240 | simplestring_addn(&elem_val->text, buf.data, buf.offset ); 241 | buffer_delete(&buf); 242 | } 243 | break; 244 | case xmlrpc_vector: 245 | { 246 | XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); 247 | XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); 248 | xml_element* root_vector_elem = elem_val; 249 | 250 | switch (my_type) { 251 | case xmlrpc_vector_array: 252 | { 253 | if(depth == 0) { 254 | elem_val->name = estrdup(ELEM_PARAMS); 255 | } 256 | else { 257 | /* Hi my name is Dave and I like to make things as confusing 258 | * as possible, thus I will throw in this 'data' element 259 | * where it absolutely does not belong just so that people 260 | * cannot code arrays and structs in a similar and straight 261 | * forward manner. Have a good day. 262 | * 263 | * GRRRRRRRRR! 264 | */ 265 | xml_element* data = xml_elem_new(); 266 | data->name = estrdup(ELEM_DATA); 267 | 268 | elem_val->name = estrdup(ELEM_ARRAY); 269 | Q_PushTail(&elem_val->children, data); 270 | root_vector_elem = data; 271 | } 272 | } 273 | break; 274 | case xmlrpc_vector_mixed: /* not officially supported */ 275 | case xmlrpc_vector_struct: 276 | elem_val->name = estrdup(ELEM_STRUCT); 277 | break; 278 | default: 279 | break; 280 | } 281 | 282 | /* recurse through sub-elements */ 283 | while ( xIter ) { 284 | xml_element* next_el = XMLRPC_to_xml_element_worker(node, xIter, request_type, depth + 1); 285 | if (next_el) { 286 | Q_PushTail(&root_vector_elem->children, next_el); 287 | } 288 | xIter = XMLRPC_VectorNext(node); 289 | } 290 | } 291 | break; 292 | default: 293 | break; 294 | } 295 | } 296 | 297 | { 298 | XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(current_vector); 299 | 300 | if (depth == 1) { 301 | xml_element* value = xml_elem_new(); 302 | value->name = estrdup(ELEM_VALUE); 303 | 304 | /* yet another hack for the "fault" crap */ 305 | if (XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)) { 306 | root = value; 307 | } 308 | else { 309 | xml_element* param = xml_elem_new(); 310 | param->name = estrdup(ELEM_PARAM); 311 | 312 | Q_PushTail(¶m->children, value); 313 | 314 | root = param; 315 | } 316 | Q_PushTail(&value->children, elem_val); 317 | } 318 | else if (vtype == xmlrpc_vector_struct || vtype == xmlrpc_vector_mixed) { 319 | xml_element* member = xml_elem_new(); 320 | xml_element* name = xml_elem_new(); 321 | xml_element* value = xml_elem_new(); 322 | 323 | member->name = estrdup(ELEM_MEMBER); 324 | name->name = estrdup(ELEM_NAME); 325 | value->name = estrdup(ELEM_VALUE); 326 | 327 | simplestring_add(&name->text, XMLRPC_GetValueID(node)); 328 | 329 | Q_PushTail(&member->children, name); 330 | Q_PushTail(&member->children, value); 331 | Q_PushTail(&value->children, elem_val); 332 | 333 | root = member; 334 | } 335 | else if (vtype == xmlrpc_vector_array) { 336 | xml_element* value = xml_elem_new(); 337 | 338 | value->name = estrdup(ELEM_VALUE); 339 | 340 | Q_PushTail(&value->children, elem_val); 341 | 342 | root = value; 343 | } 344 | else if (vtype == xmlrpc_vector_none) { 345 | /* no parent. non-op */ 346 | root = elem_val; 347 | } 348 | else { 349 | xml_element* value = xml_elem_new(); 350 | 351 | value->name = estrdup(ELEM_VALUE); 352 | 353 | Q_PushTail(&value->children, elem_val); 354 | 355 | root = value; 356 | } 357 | } 358 | } 359 | return root; 360 | } 361 | 362 | xml_element* XMLRPC_VALUE_to_xml_element(XMLRPC_VALUE node) { 363 | return XMLRPC_to_xml_element_worker(NULL, node, xmlrpc_request_none, 0); 364 | } 365 | 366 | xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { 367 | xml_element* wrapper = NULL; 368 | if (request) { 369 | const char* pStr = NULL; 370 | XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); 371 | XMLRPC_VALUE xParams = XMLRPC_RequestGetData(request); 372 | 373 | wrapper = xml_elem_new(); 374 | 375 | if (request_type == xmlrpc_request_call) { 376 | pStr = ELEM_METHODCALL; 377 | } 378 | else if (request_type == xmlrpc_request_response) { 379 | pStr = ELEM_METHODRESPONSE; 380 | } 381 | if (pStr) { 382 | wrapper->name = estrdup(pStr); 383 | } 384 | 385 | if(request_type == xmlrpc_request_call) { 386 | pStr = XMLRPC_RequestGetMethodName(request); 387 | 388 | if (pStr) { 389 | xml_element* method = xml_elem_new(); 390 | method->name = estrdup(ELEM_METHODNAME); 391 | simplestring_add(&method->text, pStr); 392 | Q_PushTail(&wrapper->children, method); 393 | } 394 | } 395 | if (xParams) { 396 | Q_PushTail(&wrapper->children, 397 | XMLRPC_to_xml_element_worker(NULL, XMLRPC_RequestGetData(request), XMLRPC_RequestGetRequestType(request), 0)); 398 | } 399 | else { 400 | /* Despite the spec, the xml-rpc list folk want me to send an empty params element */ 401 | xml_element* params = xml_elem_new(); 402 | params->name = estrdup(ELEM_PARAMS); 403 | Q_PushTail(&wrapper->children, params); 404 | } 405 | } 406 | return wrapper; 407 | } 408 | -------------------------------------------------------------------------------- /libxmlrpc/xmlrpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2000 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | #ifndef XMLRPC_ALREADY_INCLUDED 34 | #define XMLRPC_ALREADY_INCLUDED 1 35 | 36 | /* includes */ 37 | #include "xml_element.h" 38 | #include /* for time_t */ 39 | #include 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | /* allow version to be specified via compile line define */ 46 | #ifndef XMLRPC_LIB_VERSION 47 | #define XMLRPC_LIB_VERSION "0.51" 48 | #endif 49 | 50 | /* this number, representing the date, must be increased each time the API changes */ 51 | #define XMLRPC_API_NO 20020623 52 | 53 | /* this string should be changed with each packaged release */ 54 | #define XMLRPC_VERSION_STR "xmlrpc-epi v. " XMLRPC_LIB_VERSION 55 | 56 | /* where to find more info. shouldn't need to change much */ 57 | #define XMLRPC_HOME_PAGE_STR "http://xmlprc-epi.sourceforge.net/" 58 | 59 | 60 | /****d* VALUE/XMLRPC_VALUE_TYPE 61 | * NAME 62 | * XMLRPC_VALUE_TYPE 63 | * NOTES 64 | * Defines data types for XMLRPC_VALUE 65 | * Deprecated for public use. See XMLRPC_VALUE_TYPE_EASY 66 | * SEE ALSO 67 | * XMLRPC_VECTOR_TYPE 68 | * XMLRPC_REQUEST_TYPE 69 | * SOURCE 70 | */ 71 | typedef enum _XMLRPC_VALUE_TYPE { 72 | xmlrpc_none, /* not a value */ 73 | xmlrpc_empty, /* empty value, eg NULL */ 74 | xmlrpc_base64, /* base64 value, eg binary data */ 75 | xmlrpc_boolean, /* boolean [0 | 1] */ 76 | xmlrpc_datetime, /* datetime [ISO8601 | time_t] */ 77 | xmlrpc_double, /* double / floating point */ 78 | xmlrpc_int, /* integer */ 79 | xmlrpc_string, /* string */ 80 | xmlrpc_vector /* vector, aka list, array */ 81 | } XMLRPC_VALUE_TYPE; 82 | /*******/ 83 | 84 | /****d* VALUE/XMLRPC_VECTOR_TYPE 85 | * NAME 86 | * XMLRPC_VECTOR_TYPE 87 | * NOTES 88 | * Defines data types for XMLRPC_VECTOR. 89 | * Deprecated for public use. See XMLRPC_VALUE_TYPE_EASY 90 | * SEE ALSO 91 | * XMLRPC_VALUE_TYPE 92 | * XMLRPC_REQUEST_TYPE 93 | * SOURCE 94 | */ 95 | typedef enum _XMLRPC_VECTOR_TYPE { 96 | xmlrpc_vector_none, /* not an array */ 97 | xmlrpc_vector_array, /* no values may have key names */ 98 | xmlrpc_vector_mixed, /* some values may have key names */ 99 | xmlrpc_vector_struct /* all values must have key names */ 100 | } XMLRPC_VECTOR_TYPE; 101 | /*******/ 102 | 103 | /****d* VALUE/XMLRPC_VALUE_TYPE_EASY 104 | * NAME 105 | * XMLRPC_VALUE_TYPE_EASY 106 | * NOTES 107 | * Defines data types for XMLRPC_VALUE, including vector types. 108 | * SEE ALSO 109 | * XMLRPC_VECTOR_TYPE 110 | * XMLRPC_REQUEST_TYPE 111 | * SOURCE 112 | */ 113 | typedef enum _XMLRPC_VALUE_TYPE_EASY { 114 | xmlrpc_type_none, /* not a value */ 115 | xmlrpc_type_empty, /* empty value, eg NULL */ 116 | xmlrpc_type_base64, /* base64 value, eg binary data */ 117 | xmlrpc_type_boolean, /* boolean [0 | 1] */ 118 | xmlrpc_type_datetime, /* datetime [ISO8601 | time_t] */ 119 | xmlrpc_type_double, /* double / floating point */ 120 | xmlrpc_type_int, /* integer */ 121 | xmlrpc_type_string, /* string */ 122 | /* -- IMPORTANT: identical to XMLRPC_VALUE_TYPE to this point. -- */ 123 | xmlrpc_type_array, /* vector array */ 124 | xmlrpc_type_mixed, /* vector mixed */ 125 | xmlrpc_type_struct /* vector struct */ 126 | } XMLRPC_VALUE_TYPE_EASY; 127 | /*******/ 128 | 129 | 130 | /****d* VALUE/XMLRPC_REQUEST_TYPE 131 | * NAME 132 | * XMLRPC_REQUEST_TYPE 133 | * NOTES 134 | * Defines data types for XMLRPC_REQUEST 135 | * SEE ALSO 136 | * XMLRPC_VALUE_TYPE 137 | * XMLRPC_VECTOR_TYPE 138 | * SOURCE 139 | */ 140 | typedef enum _xmlrpc_request_type { 141 | xmlrpc_request_none, /* not a valid request */ 142 | xmlrpc_request_call, /* calling/invoking a method */ 143 | xmlrpc_request_response, /* responding to a method call */ 144 | } XMLRPC_REQUEST_TYPE; 145 | /*******/ 146 | 147 | /****d* VALUE/XMLRPC_ERROR_CODE 148 | * NAME 149 | * XMLRPC_ERROR_CODE 150 | * NOTES 151 | * All existing error codes 152 | * SEE ALSO 153 | * XMLRPC_REQUEST_ERROR 154 | * SOURCE 155 | */ 156 | typedef enum _xmlrpc_error_code { 157 | xmlrpc_error_none = 0, /* not an error */ 158 | xmlrpc_error_parse_xml_syntax = -32700, 159 | xmlrpc_error_parse_unknown_encoding = -32701, 160 | xmlrpc_error_parse_bad_encoding = -32702, 161 | xmlrpc_error_invalid_xmlrpc = -32600, 162 | xmlrpc_error_unknown_method = -32601, 163 | xmlrpc_error_invalid_params = -32602, 164 | xmlrpc_error_internal_server = -32603, 165 | xmlrpc_error_application = -32500, 166 | xmlrpc_error_system = -32400, 167 | xmlrpc_error_transport = -32300 168 | } XMLRPC_ERROR_CODE; 169 | /******/ 170 | 171 | #define xmlrpc_error_parse_xml_syntax_str "parse error. not well formed." 172 | #define xmlrpc_error_parse_unknown_encoding_str "parse error. unknown encoding" 173 | #define xmlrpc_error_parse_bad_encoding_str "parse error. invalid character for encoding" 174 | #define xmlrpc_error_invalid_xmlrpc_str "server error. xml-rpc not conforming to spec" 175 | #define xmlrpc_error_unknown_method_str "server error. method not found." 176 | #define xmlrpc_error_invalid_params_str "server error. invalid method parameters" 177 | #define xmlrpc_error_internal_server_str "server error. internal xmlrpc library error" 178 | #define xmlrpc_error_application_str "application error." 179 | #define xmlrpc_error_system_str "system error." 180 | #define xmlrpc_error_transport_str "transport error." 181 | 182 | 183 | 184 | /****d* VALUE/XMLRPC_VERSION 185 | * NAME 186 | * XMLRPC_VERSION 187 | * NOTES 188 | * Defines xml vocabulary used for generated xml 189 | * SEE ALSO 190 | * XMLRPC_REQUEST_OUTPUT_OPTIONS 191 | * XMLRPC_REQUEST_To_XML () 192 | * SOURCE 193 | */ 194 | typedef enum _xmlrpc_version { 195 | xmlrpc_version_none = 0, /* not a recognized vocabulary */ 196 | xmlrpc_version_1_0 = 1, /* xmlrpc 1.0 standard vocab */ 197 | xmlrpc_version_simple = 2, /* alt more readable vocab */ 198 | xmlrpc_version_danda = 2, /* same as simple. legacy */ 199 | xmlrpc_version_soap_1_1 = 3 /* SOAP. version 1.1 */ 200 | } XMLRPC_VERSION; 201 | /******/ 202 | 203 | /****s* VALUE/XMLRPC_REQUEST_OUTPUT_OPTIONS 204 | * NAME 205 | * XMLRPC_REQUEST_OUTPUT_OPTIONS 206 | * NOTES 207 | * Defines output options for generated xml 208 | * SEE ALSO 209 | * XMLRPC_VERSION 210 | * XML_ELEM_OUTPUT_OPTIONS 211 | * XMLRPC_REQUEST_To_XML () 212 | * SOURCE 213 | */ 214 | typedef struct _xmlrpc_request_output_options { 215 | STRUCT_XML_ELEM_OUTPUT_OPTIONS xml_elem_opts; /* xml_element specific output options */ 216 | XMLRPC_VERSION version; /* xml vocabulary to use */ 217 | } STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS, *XMLRPC_REQUEST_OUTPUT_OPTIONS; 218 | /******/ 219 | 220 | /****s* VALUE/XMLRPC_REQUEST_INPUT_OPTIONS 221 | * NAME 222 | * XMLRPC_REQUEST_INPUT_OPTIONS 223 | * NOTES 224 | * Defines options for reading in xml data 225 | * SEE ALSO 226 | * XMLRPC_VERSION 227 | * XML_ELEM_INPUT_OPTIONS 228 | * XMLRPC_REQUEST_From_XML () 229 | * SOURCE 230 | */ 231 | typedef struct _xmlrpc_request_input_options { 232 | STRUCT_XML_ELEM_INPUT_OPTIONS xml_elem_opts; /* xml_element specific output options */ 233 | } STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS, *XMLRPC_REQUEST_INPUT_OPTIONS; 234 | /******/ 235 | 236 | /****s* VALUE/XMLRPC_ERROR 237 | * NAME 238 | * XMLRPC_ERROR 239 | * NOTES 240 | * For the reporting and handling of errors 241 | * SOURCE 242 | */ 243 | typedef struct _xmlrpc_error { 244 | XMLRPC_ERROR_CODE code; 245 | STRUCT_XML_ELEM_ERROR xml_elem_error; /* xml_element errors (parser errors) */ 246 | } STRUCT_XMLRPC_ERROR, *XMLRPC_ERROR; 247 | /******/ 248 | 249 | 250 | /****d* VALUE/XMLRPC_CASE_COMPARISON 251 | * NAME 252 | * XMLRPC_CASE_COMPARISON 253 | * NOTES 254 | * Defines case comparison options for XMLRPC_VALUE/VECTOR API's 255 | * SEE ALSO 256 | * XMLRPC_CASE 257 | * XMLRPC_VALUE 258 | * SOURCE 259 | */ 260 | typedef enum _xmlrpc_case_comparison { 261 | xmlrpc_case_insensitive, /* use case-insensitive compare */ 262 | xmlrpc_case_sensitive /* use case-sensitive compare */ 263 | } XMLRPC_CASE_COMPARISON; 264 | /******/ 265 | 266 | /****d* VALUE/XMLRPC_CASE 267 | * NAME 268 | * XMLRPC_CASE 269 | * NOTES 270 | * Defines case behavior when setting IDs in XMLRPC_VALUE API's 271 | * SEE ALSO 272 | * XMLRPC_CASE_COMPARISON 273 | * XMLRPC_VALUE 274 | * SOURCE 275 | */ 276 | typedef enum _xmlrpc_case { 277 | xmlrpc_case_exact, /* leave case alone */ 278 | xmlrpc_case_lower, /* lower-case id */ 279 | xmlrpc_case_upper /* upper-case id */ 280 | } XMLRPC_CASE; 281 | /******/ 282 | 283 | /* if you don't like these defaults, you can set them with XMLRPC_SetDefaultIdCase*() */ 284 | #define XMLRPC_DEFAULT_ID_CASE XMLRPC_GetDefaultIdCase() 285 | #define XMLRPC_DEFAULT_ID_CASE_SENSITIVITY XMLRPC_GetDefaultIdCaseComparison() 286 | 287 | /* opaque (non-public) types. defined locally in xmlrpc.c */ 288 | typedef struct _xmlrpc_request* XMLRPC_REQUEST; 289 | typedef struct _xmlrpc_server* XMLRPC_SERVER; 290 | typedef struct _xmlrpc_value* XMLRPC_VALUE; 291 | 292 | /****d* VALUE/XMLRPC_Callback 293 | * NAME 294 | * XMLRPC_Callback 295 | * NOTES 296 | * Function prototype for user defined method handlers (callbacks). 297 | * SEE ALSO 298 | * XMLRPC_ServerRegisterMethod () 299 | * XMLRPC_ServerCallMethod () 300 | * XMLRPC_REQUEST 301 | * XMLRPC_VALUE 302 | * SOURCE 303 | */ 304 | typedef XMLRPC_VALUE (*XMLRPC_Callback)(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 305 | /******/ 306 | 307 | /* ID Case Defaults */ 308 | XMLRPC_CASE XMLRPC_GetDefaultIdCase(void); 309 | XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case); 310 | XMLRPC_CASE_COMPARISON XMLRPC_GetDefaultIdCaseComparison(void); 311 | XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON id_case); 312 | 313 | /* Vector manipulation */ 314 | int XMLRPC_VectorSize(XMLRPC_VALUE value); 315 | XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value); 316 | XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value); 317 | int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type); 318 | int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source); 319 | int XMLRPC_AddValuesToVector(XMLRPC_VALUE target, ...); 320 | int XMLRPC_VectorRemoveValue(XMLRPC_VALUE vector, XMLRPC_VALUE value); 321 | XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case(XMLRPC_VALUE vector, const char* id, XMLRPC_CASE_COMPARISON id_case); 322 | 323 | 324 | /* Create values */ 325 | XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int truth); 326 | XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len); 327 | XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time); 328 | XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s); 329 | XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double f); 330 | XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i); 331 | XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* s, int len); 332 | XMLRPC_VALUE XMLRPC_CreateValueEmpty(void); 333 | XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type); 334 | 335 | /* Cleanup values */ 336 | void XMLRPC_CleanupValue(XMLRPC_VALUE value); 337 | 338 | /* Request error */ 339 | XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error); 340 | XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request); 341 | 342 | /* Copy values */ 343 | XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value); 344 | XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE xSource); 345 | 346 | /* Set Values */ 347 | void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time); 348 | void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s); 349 | void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val); 350 | void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val); 351 | void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val); 352 | const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* s, int len); 353 | void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len); 354 | const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case); 355 | #define XMLRPC_SetValueID(value, id, len) XMLRPC_SetValueID_Case(value, id, len, XMLRPC_DEFAULT_ID_CASE) 356 | 357 | /* Get Values */ 358 | const char* XMLRPC_GetValueString(XMLRPC_VALUE value); 359 | int XMLRPC_GetValueStringLen(XMLRPC_VALUE value); 360 | int XMLRPC_GetValueInt(XMLRPC_VALUE value); 361 | int XMLRPC_GetValueBoolean(XMLRPC_VALUE value); 362 | double XMLRPC_GetValueDouble(XMLRPC_VALUE value); 363 | const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value); 364 | time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value); 365 | const char* XMLRPC_GetValueDateTime_ISO8601(XMLRPC_VALUE value); 366 | const char* XMLRPC_GetValueID(XMLRPC_VALUE value); 367 | 368 | /* Type introspection */ 369 | XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE v); 370 | XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy(XMLRPC_VALUE v); 371 | XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE v); 372 | 373 | /* Parsing and Creating XML */ 374 | XMLRPC_REQUEST XMLRPC_REQUEST_FromXML(const char* in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options); 375 | XMLRPC_VALUE XMLRPC_VALUE_FromXML(const char* in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options); 376 | char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int *buf_len); 377 | char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val, int* buf_len); 378 | 379 | /* Request manipulation funcs */ 380 | const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName); 381 | const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request); 382 | XMLRPC_REQUEST XMLRPC_RequestNew(void); 383 | void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO); 384 | XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output); 385 | XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request); 386 | XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data); 387 | XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request); 388 | XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType(XMLRPC_REQUEST request, XMLRPC_REQUEST_TYPE type); 389 | XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request); 390 | 391 | /* Server Creation/Destruction; Method Registration and Invocation */ 392 | XMLRPC_SERVER XMLRPC_ServerCreate(void); 393 | XMLRPC_SERVER XMLRPC_GetGlobalServer(void); /* better to use XMLRPC_ServerCreate if you can */ 394 | void XMLRPC_ServerDestroy(XMLRPC_SERVER server); 395 | int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb); 396 | XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName); 397 | XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData); 398 | 399 | #include "xmlrpc_introspection.h" 400 | 401 | /* Fault interrogation funcs */ 402 | int XMLRPC_ValueIsFault (XMLRPC_VALUE value); 403 | int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response); 404 | int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value); 405 | int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response); 406 | const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value); 407 | const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response); 408 | 409 | 410 | /* Public Utility funcs */ 411 | XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string); 412 | void XMLRPC_Free(void* mem); 413 | const char* XMLRPC_GetVersionString(void); 414 | 415 | /****d* VALUE/XMLRPC_MACROS 416 | * NAME 417 | * Some Helpful Macros 418 | * NOTES 419 | * Some macros for making life easier. Should be self-explanatory. 420 | * SEE ALSO 421 | * XMLRPC_AddValueToVector () 422 | * XMLRPC_VectorGetValueWithID_Case () 423 | * XMLRPC_VALUE 424 | * SOURCE 425 | */ 426 | 427 | /* Append values to vector */ 428 | #define XMLRPC_VectorAppendString(vector, id, s, len) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueString(id, s, len)) 429 | #define XMLRPC_VectorAppendBase64(vector, id, s, len) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueBase64(id, s, len)) 430 | #define XMLRPC_VectorAppendDateTime(vector, id, time) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDateTime(id, time)) 431 | #define XMLRPC_VectorAppendDateTime_ISO8601(vector, id, s) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDateTime_ISO8601(id, s)) 432 | #define XMLRPC_VectorAppendDouble(vector, id, f) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDouble(id, f)) 433 | #define XMLRPC_VectorAppendInt(vector, id, i) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueInt(id, i)) 434 | #define XMLRPC_VectorAppendBoolean(vector, id, i) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueBoolean(id, i)) 435 | 436 | /* Get named values from vector */ 437 | #define XMLRPC_VectorGetValueWithID(vector, id) XMLRPC_VectorGetValueWithID_Case(vector, id, XMLRPC_DEFAULT_ID_CASE_SENSITIVITY) 438 | #define XMLRPC_VectorGetStringWithID(vector, id) XMLRPC_GetValueString(XMLRPC_VectorGetValueWithID(vector, id)) 439 | #define XMLRPC_VectorGetBase64WithID(vector, id) XMLRPC_GetValueBase64(XMLRPC_VectorGetValueWithID(vector, id)) 440 | #define XMLRPC_VectorGetDateTimeWithID(vector, id) XMLRPC_GetValueDateTime(XMLRPC_VectorGetValueWithID(vector, id)) 441 | #define XMLRPC_VectorGetDoubleWithID(vector, id) XMLRPC_GetValueDouble(XMLRPC_VectorGetValueWithID(vector, id)) 442 | #define XMLRPC_VectorGetIntWithID(vector, id) XMLRPC_GetValueInt(XMLRPC_VectorGetValueWithID(vector, id)) 443 | #define XMLRPC_VectorGetBooleanWithID(vector, id) XMLRPC_GetValueBoolean(XMLRPC_VectorGetValueWithID(vector, id)) 444 | 445 | /******/ 446 | 447 | 448 | #ifdef __cplusplus 449 | } 450 | #endif 451 | 452 | #endif /* not XMLRPC_ALREADY_INCLUDED */ 453 | -------------------------------------------------------------------------------- /libxmlrpc/xmlrpc_introspection.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of libXMLRPC - a C library for xml-encoded function calls. 3 | 4 | Author: Dan Libby (dan@libby.com) 5 | Epinions.com may be contacted at feedback@epinions-inc.com 6 | */ 7 | 8 | /* 9 | Copyright 2001 Epinions, Inc. 10 | 11 | Subject to the following 3 conditions, Epinions, Inc. permits you, free 12 | of charge, to (a) use, copy, distribute, modify, perform and display this 13 | software and associated documentation files (the "Software"), and (b) 14 | permit others to whom the Software is furnished to do so as well. 15 | 16 | 1) The above copyright notice and this permission notice shall be included 17 | without modification in all copies or substantial portions of the 18 | Software. 19 | 20 | 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF 21 | ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY 22 | IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR 23 | PURPOSE OR NONINFRINGEMENT. 24 | 25 | 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT 27 | OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING 28 | NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH 29 | DAMAGES. 30 | 31 | */ 32 | 33 | 34 | /****h* ABOUT/xmlrpc_introspection 35 | * AUTHOR 36 | * Dan Libby, aka danda (dan@libby.com) 37 | * HISTORY 38 | * $Log$ 39 | * Revision 1.4 2003/12/16 21:00:21 sniper 40 | * Fix some compile warnings (patch by Joe Orton) 41 | * 42 | * Revision 1.3 2002/07/05 04:43:53 danda 43 | * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 44 | * 45 | * Revision 1.9 2001/09/29 21:58:05 danda 46 | * adding cvs log to history section 47 | * 48 | * 4/10/2001 -- danda -- initial introspection support 49 | * TODO 50 | * NOTES 51 | *******/ 52 | 53 | 54 | #include "queue.h" 55 | #include "xmlrpc.h" 56 | #include "xmlrpc_private.h" 57 | #include "xmlrpc_introspection_private.h" 58 | #include 59 | #include 60 | #include 61 | 62 | 63 | /* forward declarations for static (non public, non api) funcs */ 64 | static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 65 | static XMLRPC_VALUE xi_system_list_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 66 | static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 67 | static XMLRPC_VALUE xi_system_method_help_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); 68 | 69 | 70 | /*-********************************** 71 | * Introspection Callbacks (methods) * 72 | ************************************/ 73 | 74 | /* iterates through a list of structs and finds the one with key "name" matching 75 | * needle. slow, would benefit from a struct key hash. 76 | */ 77 | static inline XMLRPC_VALUE find_named_value(XMLRPC_VALUE list, const char* needle) { 78 | XMLRPC_VALUE xIter = XMLRPC_VectorRewind(list); 79 | while(xIter) { 80 | const char* name = XMLRPC_VectorGetStringWithID(xIter, xi_token_name); 81 | if(name && !strcmp(name, needle)) { 82 | return xIter; 83 | } 84 | xIter = XMLRPC_VectorNext(list); 85 | } 86 | return NULL; 87 | } 88 | 89 | 90 | /* iterates through docs callbacks and calls any that have not yet been called */ 91 | static void check_docs_loaded(XMLRPC_SERVER server, void* userData) { 92 | if(server) { 93 | q_iter qi = Q_Iter_Head_F(&server->docslist); 94 | while( qi ) { 95 | doc_method* dm = Q_Iter_Get_F(qi); 96 | if(dm && !dm->b_called) { 97 | dm->method(server, userData); 98 | dm->b_called = 1; 99 | } 100 | qi = Q_Iter_Next_F(qi); 101 | } 102 | } 103 | } 104 | 105 | 106 | /* utility function for xi_system_describe_methods_cb */ 107 | static inline void describe_method(XMLRPC_SERVER server, XMLRPC_VALUE vector, const char* method) { 108 | if(method) { 109 | server_method* sm = find_method(server, method); 110 | if(sm) { 111 | XMLRPC_AddValueToVector(vector, sm->desc); 112 | } 113 | } 114 | } 115 | 116 | 117 | 118 | /* system.describeMethods() callback */ 119 | static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 120 | XMLRPC_VALUE xParams = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); 121 | XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); 122 | XMLRPC_VALUE xMethodList = XMLRPC_CreateVector("methodList", xmlrpc_vector_array); 123 | XMLRPC_VALUE xTypeList = NULL; 124 | int bAll = 1; 125 | 126 | /* lazy loading of introspection data */ 127 | check_docs_loaded(server, userData); 128 | 129 | xTypeList = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); 130 | 131 | XMLRPC_AddValueToVector(xResponse, xTypeList); 132 | XMLRPC_AddValueToVector(xResponse, xMethodList); 133 | 134 | /* check if we have any param */ 135 | if(xParams) { 136 | /* check if string or vector (1 or n) */ 137 | XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(xParams); 138 | if(type == xmlrpc_string) { 139 | /* just one. spit it out. */ 140 | describe_method(server, xMethodList, XMLRPC_GetValueString(xParams)); 141 | bAll = 0; 142 | } 143 | else if(type == xmlrpc_vector) { 144 | /* multiple. spit all out */ 145 | XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xParams); 146 | while(xIter) { 147 | describe_method(server, xMethodList, XMLRPC_GetValueString(xIter)); 148 | xIter = XMLRPC_VectorNext(xParams); 149 | } 150 | bAll = 0; 151 | } 152 | } 153 | 154 | /* otherwise, default to sending all methods */ 155 | if(bAll) { 156 | q_iter qi = Q_Iter_Head_F(&server->methodlist); 157 | while( qi ) { 158 | server_method* sm = Q_Iter_Get_F(qi); 159 | if(sm) { 160 | XMLRPC_AddValueToVector(xMethodList, sm->desc); 161 | } 162 | qi = Q_Iter_Next_F(qi); 163 | } 164 | } 165 | 166 | return xResponse; 167 | } 168 | 169 | /* this complies with system.listMethods as defined at http://xmlrpc.usefulinc.com/doc/reserved.html */ 170 | static XMLRPC_VALUE xi_system_list_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 171 | XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); 172 | 173 | q_iter qi = Q_Iter_Head_F(&server->methodlist); 174 | while( qi ) { 175 | server_method* sm = Q_Iter_Get_F(qi); 176 | if(sm) { 177 | XMLRPC_VectorAppendString(xResponse, 0, sm->name, 0); 178 | } 179 | qi = Q_Iter_Next_F(qi); 180 | } 181 | return xResponse; 182 | } 183 | 184 | /* this complies with system.methodSignature as defined at 185 | * http://xmlrpc.usefulinc.com/doc/sysmethodsig.html 186 | */ 187 | static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 188 | const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); 189 | XMLRPC_VALUE xResponse = NULL; 190 | 191 | /* lazy loading of introspection data */ 192 | check_docs_loaded(server, userData); 193 | 194 | if(method) { 195 | server_method* sm = find_method(server, method); 196 | if(sm && sm->desc) { 197 | XMLRPC_VALUE xTypesArray = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); 198 | XMLRPC_VALUE xIter, xParams, xSig, xSigIter; 199 | const char* type; 200 | 201 | /* array of possible signatures. */ 202 | xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); 203 | 204 | /* find first signature */ 205 | xSig = XMLRPC_VectorGetValueWithID(sm->desc, xi_token_signatures); 206 | xSigIter = XMLRPC_VectorRewind( xSig ); 207 | 208 | /* iterate through sigs */ 209 | while(xSigIter) { 210 | /* first type is the return value */ 211 | type = XMLRPC_VectorGetStringWithID(XMLRPC_VectorRewind( 212 | XMLRPC_VectorGetValueWithID(xSigIter, xi_token_returns)), 213 | xi_token_type); 214 | XMLRPC_AddValueToVector(xTypesArray, 215 | XMLRPC_CreateValueString(NULL, 216 | type ? type : type_to_str(xmlrpc_none, 0), 217 | 0)); 218 | 219 | /* the rest are parameters */ 220 | xParams = XMLRPC_VectorGetValueWithID(xSigIter, xi_token_params); 221 | xIter = XMLRPC_VectorRewind(xParams); 222 | 223 | /* iter through params, adding to types array */ 224 | while(xIter) { 225 | XMLRPC_AddValueToVector(xTypesArray, 226 | XMLRPC_CreateValueString(NULL, 227 | XMLRPC_VectorGetStringWithID(xIter, xi_token_type), 228 | 0)); 229 | xIter = XMLRPC_VectorNext(xParams); 230 | } 231 | 232 | /* add types for this signature */ 233 | XMLRPC_AddValueToVector(xResponse, xTypesArray); 234 | 235 | xSigIter = XMLRPC_VectorNext( xSig ); 236 | } 237 | } 238 | } 239 | 240 | return xResponse; 241 | } 242 | 243 | /* this complies with system.methodHelp as defined at 244 | * http://xmlrpc.usefulinc.com/doc/sysmethhelp.html 245 | */ 246 | static XMLRPC_VALUE xi_system_method_help_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { 247 | const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); 248 | XMLRPC_VALUE xResponse = NULL; 249 | 250 | /* lazy loading of introspection data */ 251 | check_docs_loaded(server, userData); 252 | 253 | if(method) { 254 | server_method* sm = find_method(server, method); 255 | if(sm && sm->desc) { 256 | const char* help = XMLRPC_VectorGetStringWithID(sm->desc, xi_token_purpose); 257 | 258 | /* returns a documentation string, or empty string */ 259 | xResponse = XMLRPC_CreateValueString(NULL, help ? help : xi_token_empty, 0); 260 | } 261 | } 262 | 263 | return xResponse; 264 | } 265 | 266 | /*-************************************** 267 | * End Introspection Callbacks (methods) * 268 | ****************************************/ 269 | 270 | 271 | /*-************************ 272 | * Introspection Utilities * 273 | **************************/ 274 | 275 | /* performs registration of introspection methods */ 276 | void xi_register_system_methods(XMLRPC_SERVER server) { 277 | XMLRPC_ServerRegisterMethod(server, xi_token_system_list_methods, xi_system_list_methods_cb); 278 | XMLRPC_ServerRegisterMethod(server, xi_token_system_method_help, xi_system_method_help_cb); 279 | XMLRPC_ServerRegisterMethod(server, xi_token_system_method_signature, xi_system_method_signature_cb); 280 | XMLRPC_ServerRegisterMethod(server, xi_token_system_describe_methods, xi_system_describe_methods_cb); 281 | } 282 | 283 | /* describe a value (param, return, type) */ 284 | static XMLRPC_VALUE describeValue_worker(const char* type, const char* id, const char* desc, int optional, const char* default_val, XMLRPC_VALUE sub_params) { 285 | XMLRPC_VALUE xParam = NULL; 286 | if(id || desc) { 287 | xParam = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); 288 | XMLRPC_VectorAppendString(xParam, xi_token_name, id, 0); 289 | XMLRPC_VectorAppendString(xParam, xi_token_type, type, 0); 290 | XMLRPC_VectorAppendString(xParam, xi_token_description, desc, 0); 291 | if(optional != 2) { 292 | XMLRPC_VectorAppendInt(xParam, xi_token_optional, optional); 293 | } 294 | if(optional == 1 && default_val) { 295 | XMLRPC_VectorAppendString(xParam, xi_token_default, default_val, 0); 296 | } 297 | XMLRPC_AddValueToVector(xParam, sub_params); 298 | } 299 | return xParam; 300 | } 301 | 302 | 303 | /* convert an xml tree conforming to spec to XMLRPC_VALUE 304 | * suitable for use with XMLRPC_ServerAddIntrospectionData 305 | */ 306 | XMLRPC_VALUE xml_element_to_method_description(xml_element* el, XMLRPC_ERROR err) { 307 | XMLRPC_VALUE xReturn = NULL; 308 | 309 | if(el->name) { 310 | const char* name = NULL; 311 | const char* type = NULL; 312 | const char* basetype = NULL; 313 | const char* desc = NULL; 314 | const char* def = NULL; 315 | int optional = 0; 316 | xml_element_attr* attr_iter = Q_Head(&el->attrs); 317 | 318 | /* grab element attributes up front to save redundant while loops */ 319 | while(attr_iter) { 320 | if(!strcmp(attr_iter->key, "name")) { 321 | name = attr_iter->val; 322 | } 323 | else if(!strcmp(attr_iter->key, "type")) { 324 | type = attr_iter->val; 325 | } 326 | else if(!strcmp(attr_iter->key, "basetype")) { 327 | basetype = attr_iter->val; 328 | } 329 | else if(!strcmp(attr_iter->key, "desc")) { 330 | desc = attr_iter->val; 331 | } 332 | else if(!strcmp(attr_iter->key, "optional")) { 333 | if(attr_iter->val && !strcmp(attr_iter->val, "yes")) { 334 | optional = 1; 335 | } 336 | } 337 | else if(!strcmp(attr_iter->key, "default")) { 338 | def = attr_iter->val; 339 | } 340 | attr_iter = Q_Next(&el->attrs); 341 | } 342 | 343 | /* value and typeDescription behave about the same */ 344 | if(!strcmp(el->name, "value") || !strcmp(el->name, "typeDescription")) { 345 | XMLRPC_VALUE xSubList = NULL; 346 | const char* ptype = !strcmp(el->name, "value") ? type : basetype; 347 | if(ptype) { 348 | if(Q_Size(&el->children) && 349 | (!strcmp(ptype, "array") || !strcmp(ptype, "struct") || !strcmp(ptype, "mixed"))) { 350 | xSubList = XMLRPC_CreateVector("member", xmlrpc_vector_array); 351 | 352 | if(xSubList) { 353 | xml_element* elem_iter = Q_Head(&el->children); 354 | while(elem_iter) { 355 | XMLRPC_AddValueToVector(xSubList, 356 | xml_element_to_method_description(elem_iter, err)); 357 | elem_iter = Q_Next(&el->children); 358 | } 359 | } 360 | } 361 | xReturn = describeValue_worker(ptype, name, (desc ? desc : (xSubList ? NULL : el->text.str)), optional, def, xSubList); 362 | } 363 | } 364 | 365 | /* these three kids are about equivalent */ 366 | else if(!strcmp(el->name, "params") || 367 | !strcmp(el->name, "returns") || 368 | !strcmp(el->name, "signature")) { 369 | if(Q_Size(&el->children)) { 370 | xml_element* elem_iter = Q_Head(&el->children); 371 | xReturn = XMLRPC_CreateVector(!strcmp(el->name, "signature") ? NULL : el->name, xmlrpc_vector_struct); 372 | 373 | 374 | while(elem_iter) { 375 | XMLRPC_AddValueToVector(xReturn, 376 | xml_element_to_method_description(elem_iter, err)); 377 | elem_iter = Q_Next(&el->children); 378 | } 379 | } 380 | } 381 | 382 | 383 | else if(!strcmp(el->name, "methodDescription")) { 384 | xml_element* elem_iter = Q_Head(&el->children); 385 | xReturn = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); 386 | 387 | XMLRPC_VectorAppendString(xReturn, xi_token_name, name, 0); 388 | 389 | while(elem_iter) { 390 | XMLRPC_AddValueToVector(xReturn, 391 | xml_element_to_method_description(elem_iter, err)); 392 | elem_iter = Q_Next(&el->children); 393 | } 394 | } 395 | 396 | /* items are slightly special */ 397 | else if(!strcmp(el->name, "item")) { 398 | xReturn = XMLRPC_CreateValueString(name, el->text.str, el->text.len); 399 | } 400 | 401 | /* sure. we'll let any ol element with children through */ 402 | else if(Q_Size(&el->children)) { 403 | xml_element* elem_iter = Q_Head(&el->children); 404 | xReturn = XMLRPC_CreateVector(el->name, xmlrpc_vector_mixed); 405 | 406 | while(elem_iter) { 407 | XMLRPC_AddValueToVector(xReturn, 408 | xml_element_to_method_description(elem_iter, err)); 409 | elem_iter = Q_Next(&el->children); 410 | } 411 | } 412 | 413 | /* or anything at all really, so long as its got some text. 414 | * no reason being all snotty about a spec, right? 415 | */ 416 | else if(el->name && el->text.len) { 417 | xReturn = XMLRPC_CreateValueString(el->name, el->text.str, el->text.len); 418 | } 419 | } 420 | 421 | return xReturn; 422 | } 423 | 424 | /*-**************************** 425 | * End Introspection Utilities * 426 | ******************************/ 427 | 428 | 429 | 430 | /*-****************** 431 | * Introspection API * 432 | ********************/ 433 | 434 | 435 | /****f* VALUE/XMLRPC_IntrospectionCreateDescription 436 | * NAME 437 | * XMLRPC_IntrospectionCreateDescription 438 | * SYNOPSIS 439 | * XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR err) 440 | * FUNCTION 441 | * converts raw xml describing types and methods into an 442 | * XMLRPC_VALUE suitable for use with XMLRPC_ServerAddIntrospectionData() 443 | * INPUTS 444 | * xml - xml data conforming to introspection spec at 445 | * err - optional pointer to error struct. filled in if error occurs and not NULL. 446 | * RESULT 447 | * XMLRPC_VALUE - newly created value, or NULL if fatal error. 448 | * BUGS 449 | * Currently does little or no validation of xml. 450 | * Only parse errors are currently reported in err, not structural errors. 451 | * SEE ALSO 452 | * XMLRPC_ServerAddIntrospectionData () 453 | * SOURCE 454 | */ 455 | XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR err) { 456 | XMLRPC_VALUE xReturn = NULL; 457 | xml_element* root = xml_elem_parse_buf(xml, 0, 0, err ? &err->xml_elem_error : NULL); 458 | 459 | if(root) { 460 | xReturn = xml_element_to_method_description(root, err); 461 | 462 | xml_elem_free(root); 463 | } 464 | 465 | return xReturn; 466 | 467 | } 468 | /*******/ 469 | 470 | 471 | /****f* SERVER/XMLRPC_ServerAddIntrospectionData 472 | * NAME 473 | * XMLRPC_ServerAddIntrospectionData 474 | * SYNOPSIS 475 | * int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) 476 | * FUNCTION 477 | * updates server with additional introspection data 478 | * INPUTS 479 | * server - target server 480 | * desc - introspection data, should be a struct generated by 481 | * XMLRPC_IntrospectionCreateDescription () 482 | * RESULT 483 | * int - 1 if success, else 0 484 | * NOTES 485 | * - function will fail if neither typeList nor methodList key is present in struct. 486 | * - if method or type already exists, it will be replaced. 487 | * - desc is never freed by the server. caller is responsible for cleanup. 488 | * BUGS 489 | * - horribly slow lookups. prime candidate for hash improvements. 490 | * - uglier and more complex than I like to see for API functions. 491 | * SEE ALSO 492 | * XMLRPC_ServerAddIntrospectionData () 493 | * XMLRPC_ServerRegisterIntrospectionCallback () 494 | * XMLRPC_CleanupValue () 495 | * SOURCE 496 | */ 497 | int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) { 498 | int bSuccess = 0; 499 | if(server && desc) { 500 | XMLRPC_VALUE xNewTypes = XMLRPC_VectorGetValueWithID(desc, "typeList"); 501 | XMLRPC_VALUE xNewMethods = XMLRPC_VectorGetValueWithID(desc, "methodList"); 502 | XMLRPC_VALUE xServerTypes = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); 503 | 504 | if(xNewMethods) { 505 | XMLRPC_VALUE xMethod = XMLRPC_VectorRewind(xNewMethods); 506 | 507 | while(xMethod) { 508 | const char* name = XMLRPC_VectorGetStringWithID(xMethod, xi_token_name); 509 | server_method* sm = find_method(server, name); 510 | 511 | if(sm) { 512 | if(sm->desc) { 513 | XMLRPC_CleanupValue(sm->desc); 514 | } 515 | sm->desc = XMLRPC_CopyValue(xMethod); 516 | bSuccess = 1; 517 | } 518 | 519 | xMethod = XMLRPC_VectorNext(xNewMethods); 520 | } 521 | } 522 | if(xNewTypes) { 523 | if(!xServerTypes) { 524 | if(!server->xIntrospection) { 525 | server->xIntrospection = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); 526 | } 527 | 528 | XMLRPC_AddValueToVector(server->xIntrospection, xNewTypes); 529 | bSuccess = 1; 530 | } 531 | else { 532 | XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xNewTypes); 533 | while(xIter) { 534 | /* get rid of old values */ 535 | XMLRPC_VALUE xPrev = find_named_value(xServerTypes, XMLRPC_VectorGetStringWithID(xIter, xi_token_name)); 536 | if(xPrev) { 537 | XMLRPC_VectorRemoveValue(xServerTypes, xPrev); 538 | } 539 | XMLRPC_AddValueToVector(xServerTypes, xIter); 540 | bSuccess = 1; 541 | xIter = XMLRPC_VectorNext(xNewTypes); 542 | } 543 | } 544 | } 545 | } 546 | return bSuccess; 547 | } 548 | /*******/ 549 | 550 | 551 | /****f* SERVER/XMLRPC_ServerRegisterIntrospectionCallback 552 | * NAME 553 | * XMLRPC_ServerRegisterIntrospectionCallback 554 | * SYNOPSIS 555 | * int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb) 556 | * FUNCTION 557 | * registers a callback for lazy generation of introspection data 558 | * INPUTS 559 | * server - target server 560 | * cb - callback that will generate introspection data 561 | * RESULT 562 | * int - 1 if success, else 0 563 | * NOTES 564 | * parsing xml and generating introspection data is fairly expensive, thus a 565 | * server may wish to wait until this data is actually requested before generating 566 | * it. Any number of callbacks may be registered at any time. A given callback 567 | * will only ever be called once, the first time an introspection request is 568 | * processed after the time of callback registration. 569 | * SEE ALSO 570 | * XMLRPC_ServerAddIntrospectionData () 571 | * XMLRPC_IntrospectionCreateDescription () 572 | * SOURCE 573 | */ 574 | int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb) { 575 | int bSuccess = 0; 576 | if(server && cb) { 577 | 578 | doc_method* dm = ecalloc(1, sizeof(doc_method)); 579 | 580 | if(dm) { 581 | dm->method = cb; 582 | dm->b_called = 0; 583 | 584 | if(Q_PushTail(&server->docslist, dm)) { 585 | bSuccess = 1; 586 | } 587 | else { 588 | my_free(dm); 589 | } 590 | } 591 | } 592 | return bSuccess; 593 | } 594 | /*******/ 595 | 596 | /*-********************** 597 | * End Introspection API * 598 | ************************/ 599 | --------------------------------------------------------------------------------