├── 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 |
--------------------------------------------------------------------------------