From: Thierry Parmentelat Date: Mon, 13 Feb 2017 13:50:28 +0000 (+0100) Subject: our own xmlrpc build is about supporting - aka allow_none=True X-Git-Tag: plcapi-5.4-0~11^2 X-Git-Url: http://git.onelab.eu/?p=plcapi.git;a=commitdiff_plain;h=e48b0945a0f03a51019f72399ac9f0eeabb90211 our own xmlrpc build is about supporting - aka allow_none=True http://gggeek.github.io/phpxmlrpc/ states that the extension is supported by mainstream - and probably has been for a while - this change is about dropping our own stuff and using mainstream xmlrpc instead pretext is fedora25 b/c this won’t build anymore but again it’s probably OK w/ f24 and way before --- diff --git a/Makefile b/Makefile index 3f61822..97061a5 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ # starting with 5.0, support for these two modules is taken out # Other stuff - doc not implicit, it's redone by myplc-docs -subdirs := php/xmlrpc # autoconf compatible variables DESTDIR := / @@ -19,7 +18,7 @@ bindir := /usr/bin PWD := $(shell pwd) -all: $(subdirs) +all: python setup.py build install: @@ -27,15 +26,9 @@ install: --install-purelib=$(DESTDIR)/$(datadir)/plc_api \ --install-scripts=$(DESTDIR)/$(datadir)/plc_api \ --install-data=$(DESTDIR)/$(datadir)/plc_api - install -D -m 755 php/xmlrpc/xmlrpc.so $(DESTDIR)/$(shell php-config --extension-dir)/xmlrpc.so - -$(subdirs): %: - $(MAKE) -C $@ clean: find . -name '*.pyc' | xargs rm -f - rm -f $(INIT) - for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir clean ; done python setup.py clean && rm -rf build index: @@ -45,7 +38,7 @@ index: force: -.PHONY: all install force clean index tags $(subdirs) +.PHONY: all install force clean index tags #################### devel tools tags: diff --git a/php/xmlrpc/CREDITS b/php/xmlrpc/CREDITS deleted file mode 100644 index cfb14fa..0000000 --- a/php/xmlrpc/CREDITS +++ /dev/null @@ -1,2 +0,0 @@ -xmlrpc -Dan Libby diff --git a/php/xmlrpc/EXPERIMENTAL b/php/xmlrpc/EXPERIMENTAL deleted file mode 100644 index 6443e99..0000000 --- a/php/xmlrpc/EXPERIMENTAL +++ /dev/null @@ -1,5 +0,0 @@ -this extension is experimental, -its functions may change their names -or move to extension all together -so do not rely to much on them -you have been warned! diff --git a/php/xmlrpc/Makefile b/php/xmlrpc/Makefile deleted file mode 100644 index e122329..0000000 --- a/php/xmlrpc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Build xmlrpc.so PHP extension -# -# Mark Huang -# Copyright (C) 2006 The Trustees of Princeton University -# - -CC := gcc -CFLAGS := -g -O2 -I. -Ilibxmlrpc -fPIC -CFLAGS += $(shell php-config --includes) -CFLAGS += $(shell xml2-config --cflags) - -LDFLAGS := -shared --export-dynamic -LIBS := -lexpat - -# for building on fedora 8 -ifneq "$(shell ld --help | grep build-id)" "" -#not needed# CFLAGS += -Wl,--build-id -LD += --build-id -endif - -all: xmlrpc.so - -xmlrpc.so: xmlrpc-epi-php.o $(patsubst %.c, %.o, $(wildcard libxmlrpc/*.c)) - $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) - -clean: - rm -f *.o libxmlrpc/*.o *.so - -.PHONY: all clean diff --git a/php/xmlrpc/config.m4 b/php/xmlrpc/config.m4 deleted file mode 100644 index 54335df..0000000 --- a/php/xmlrpc/config.m4 +++ /dev/null @@ -1,93 +0,0 @@ -dnl -dnl $Id$ -dnl - -sinclude(ext/xmlrpc/libxmlrpc/acinclude.m4) -sinclude(ext/xmlrpc/libxmlrpc/xmlrpc.m4) -sinclude(libxmlrpc/acinclude.m4) -sinclude(libxmlrpc/xmlrpc.m4) - -PHP_ARG_WITH(xmlrpc, for XMLRPC-EPI support, -[ --with-xmlrpc[=DIR] Include XMLRPC-EPI support.]) - -PHP_ARG_WITH(expat-dir, libexpat dir for XMLRPC-EPI, -[ --with-expat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI.],no,no) - -PHP_ARG_WITH(iconv-dir, iconv dir for XMLRPC-EPI, -[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI.],no,no) - -if test "$PHP_XMLRPC" != "no"; then - - PHP_SUBST(XMLRPC_SHARED_LIBADD) - AC_DEFINE(HAVE_XMLRPC,1,[ ]) - - testval=no - for i in $PHP_EXPAT_DIR $XMLRPC_DIR /usr/local /usr; do - if test -f $i/$PHP_LIBDIR/libexpat.a -o -f $i/$PHP_LIBDIR/libexpat.$SHLIB_SUFFIX_NAME; then - AC_DEFINE(HAVE_LIBEXPAT2,1,[ ]) - PHP_ADD_LIBRARY_WITH_PATH(expat, $i/$PHP_LIBDIR, XMLRPC_SHARED_LIBADD) - PHP_ADD_INCLUDE($i/include) - testval=yes - break - fi - done - - if test "$testval" = "no"; then - AC_MSG_ERROR(XML-RPC support requires libexpat. Use --with-expat-dir=) - fi - - if test "$PHP_ICONV_DIR" != "no"; then - PHP_ICONV=$PHP_ICONV_DIR - fi - - if test "$PHP_ICONV" = "no"; then - PHP_ICONV=yes - fi - - PHP_SETUP_ICONV(XMLRPC_SHARED_LIBADD, [], [ - AC_MSG_ERROR([iconv not found, in order to build xmlrpc you need the iconv library]) - ]) -fi - - -if test "$PHP_XMLRPC" = "yes"; then - XMLRPC_CHECKS - PHP_NEW_EXTENSION(xmlrpc,xmlrpc-epi-php.c libxmlrpc/base64.c \ - libxmlrpc/simplestring.c libxmlrpc/xml_to_dandarpc.c \ - libxmlrpc/xmlrpc_introspection.c libxmlrpc/encodings.c \ - libxmlrpc/system_methods.c libxmlrpc/xml_to_xmlrpc.c \ - libxmlrpc/queue.c libxmlrpc/xml_element.c libxmlrpc/xmlrpc.c \ - libxmlrpc/xml_to_soap.c,$ext_shared,, - -I@ext_srcdir@/libxmlrpc -DVERSION="0.50") - PHP_ADD_BUILD_DIR($ext_builddir/libxmlrpc) - XMLRPC_MODULE_TYPE=builtin - -elif test "$PHP_XMLRPC" != "no"; then - - if test -r $PHP_XMLRPC/include/xmlrpc.h; then - XMLRPC_DIR=$PHP_XMLRPC/include - elif test -r $PHP_XMLRPC/include/xmlrpc-epi/xmlrpc.h; then -dnl some xmlrpc-epi header files have generic file names like -dnl queue.h or base64.h. Distributions have to create dir -dnl for xmlrpc-epi because of this. - XMLRPC_DIR=$PHP_XMLRPC/include/xmlrpc-epi - else - AC_MSG_CHECKING(for XMLRPC-EPI in default path) - for i in /usr/local /usr; do - if test -r $i/include/xmlrpc.h; then - XMLRPC_DIR=$i/include - AC_MSG_RESULT(found in $i) - break - fi - done - fi - - if test -z "$XMLRPC_DIR"; then - AC_MSG_RESULT(not found) - AC_MSG_ERROR(Please reinstall the XMLRPC-EPI distribution) - fi - - PHP_ADD_INCLUDE($XMLRPC_DIR) - PHP_ADD_LIBRARY_WITH_PATH(xmlrpc, $XMLRPC_DIR/$PHP_LIBDIR, XMLRPC_SHARED_LIBADD) -fi - diff --git a/php/xmlrpc/config.m4.lib64 b/php/xmlrpc/config.m4.lib64 deleted file mode 100644 index 8551f6b..0000000 --- a/php/xmlrpc/config.m4.lib64 +++ /dev/null @@ -1,93 +0,0 @@ -dnl -dnl $Id$ -dnl - -sinclude(ext/xmlrpc/libxmlrpc/acinclude.m4) -sinclude(ext/xmlrpc/libxmlrpc/xmlrpc.m4) -sinclude(libxmlrpc/acinclude.m4) -sinclude(libxmlrpc/xmlrpc.m4) - -PHP_ARG_WITH(xmlrpc, for XMLRPC-EPI support, -[ --with-xmlrpc[=DIR] Include XMLRPC-EPI support.]) - -PHP_ARG_WITH(expat-dir, libexpat dir for XMLRPC-EPI, -[ --with-expat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI.],no,no) - -PHP_ARG_WITH(iconv-dir, iconv dir for XMLRPC-EPI, -[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI.],no,no) - -if test "$PHP_XMLRPC" != "no"; then - - PHP_SUBST(XMLRPC_SHARED_LIBADD) - AC_DEFINE(HAVE_XMLRPC,1,[ ]) - - testval=no - for i in $PHP_EXPAT_DIR $XMLRPC_DIR /usr/local /usr; do - if test -f $i/lib/libexpat.a -o -f $i/lib/libexpat.$SHLIB_SUFFIX_NAME; then - AC_DEFINE(HAVE_LIBEXPAT2,1,[ ]) - PHP_ADD_LIBRARY_WITH_PATH(expat, $i/lib, XMLRPC_SHARED_LIBADD) - PHP_ADD_INCLUDE($i/include) - testval=yes - break - fi - done - - if test "$testval" = "no"; then - AC_MSG_ERROR(XML-RPC support requires libexpat. Use --with-expat-dir=) - fi - - if test "$PHP_ICONV_DIR" != "no"; then - PHP_ICONV=$PHP_ICONV_DIR - fi - - if test "$PHP_ICONV" = "no"; then - PHP_ICONV=yes - fi - - PHP_SETUP_ICONV(XMLRPC_SHARED_LIBADD, [], [ - AC_MSG_ERROR([iconv not found, in order to build xmlrpc you need the iconv library]) - ]) -fi - - -if test "$PHP_XMLRPC" = "yes"; then - XMLRPC_CHECKS - PHP_NEW_EXTENSION(xmlrpc,xmlrpc-epi-php.c libxmlrpc/base64.c \ - libxmlrpc/simplestring.c libxmlrpc/xml_to_dandarpc.c \ - libxmlrpc/xmlrpc_introspection.c libxmlrpc/encodings.c \ - libxmlrpc/system_methods.c libxmlrpc/xml_to_xmlrpc.c \ - libxmlrpc/queue.c libxmlrpc/xml_element.c libxmlrpc/xmlrpc.c \ - libxmlrpc/xml_to_soap.c,$ext_shared,, - -I@ext_srcdir@/libxmlrpc -DVERSION="0.50") - PHP_ADD_BUILD_DIR($ext_builddir/libxmlrpc) - XMLRPC_MODULE_TYPE=builtin - -elif test "$PHP_XMLRPC" != "no"; then - - if test -r $PHP_XMLRPC/include/xmlrpc.h; then - XMLRPC_DIR=$PHP_XMLRPC/include - elif test -r $PHP_XMLRPC/include/xmlrpc-epi/xmlrpc.h; then -dnl some xmlrpc-epi header files have generic file names like -dnl queue.h or base64.h. Distributions have to create dir -dnl for xmlrpc-epi because of this. - XMLRPC_DIR=$PHP_XMLRPC/include/xmlrpc-epi - else - AC_MSG_CHECKING(for XMLRPC-EPI in default path) - for i in /usr/local /usr; do - if test -r $i/include/xmlrpc.h; then - XMLRPC_DIR=$i/include - AC_MSG_RESULT(found in $i) - break - fi - done - fi - - if test -z "$XMLRPC_DIR"; then - AC_MSG_RESULT(not found) - AC_MSG_ERROR(Please reinstall the XMLRPC-EPI distribution) - fi - - PHP_ADD_INCLUDE($XMLRPC_DIR) - PHP_ADD_LIBRARY_WITH_PATH(xmlrpc, $XMLRPC_DIR/lib, XMLRPC_SHARED_LIBADD) -fi - diff --git a/php/xmlrpc/config.w32 b/php/xmlrpc/config.w32 deleted file mode 100644 index 8c399cd..0000000 --- a/php/xmlrpc/config.w32 +++ /dev/null @@ -1,14 +0,0 @@ -// $Id$ -// vim:ft=javascript - -ARG_WITH("xmlrpc", "XMLRPC-EPI support", "no"); - -if (PHP_XMLRPC != "no") { - CHECK_HEADER_ADD_INCLUDE("xmlrpc.h", "CFLAGS_XMLRPC", configure_module_dirname + "/libxmlrpc"); - EXTENSION('xmlrpc', 'xmlrpc-epi-php.c', PHP_XMLRPC_SHARED, "-DVERSION=\"0.50\""); - ADD_SOURCES(configure_module_dirname + "/libxmlrpc", "base64.c simplestring.c xml_to_dandarpc.c \ - xmlrpc_introspection.c encodings.c system_methods.c xml_to_xmlrpc.c \ - queue.c xml_element.c xmlrpc.c xml_to_soap.c", "xmlrpc"); - ADD_EXTENSION_DEP('xmlrpc', 'libxml'); -} - diff --git a/php/xmlrpc/libxmlrpc/README b/php/xmlrpc/libxmlrpc/README deleted file mode 100644 index 323edfa..0000000 --- a/php/xmlrpc/libxmlrpc/README +++ /dev/null @@ -1,17 +0,0 @@ -organization of this directory is moving towards this approach: - -.h -- public API and data types -_private.h -- protected API and data types -.c -- implementation and private API / types - -The rules are: -.c files may include *_private.h. -.h files may not include *_private.h - -This allows us to have a nicely encapsulated C api with opaque data types and private functions -that are nonetheless shared between source files without redundant extern declarations.. - - - - - diff --git a/php/xmlrpc/libxmlrpc/acinclude.m4 b/php/xmlrpc/libxmlrpc/acinclude.m4 deleted file mode 100644 index 49b6090..0000000 --- a/php/xmlrpc/libxmlrpc/acinclude.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# Local macros for automake & autoconf - -AC_DEFUN([XMLRPC_FUNCTION_CHECKS],[ - -# Standard XMLRPC list -AC_CHECK_FUNCS( \ - strtoul strtoull snprintf \ - strstr strpbrk strerror\ - memcpy memmove) - -]) - -AC_DEFUN([XMLRPC_HEADER_CHECKS],[ -AC_HEADER_STDC -AC_CHECK_HEADERS(xmlparse.h xmltok.h stdlib.h strings.h string.h) -]) - -AC_DEFUN([XMLRPC_TYPE_CHECKS],[ - -AC_REQUIRE([AC_C_CONST]) -AC_REQUIRE([AC_C_INLINE]) -AC_CHECK_SIZEOF(char, 1) - -AC_CHECK_SIZEOF(int, 4) -AC_CHECK_SIZEOF(long, 4) -AC_CHECK_SIZEOF(long long, 8) -AC_TYPE_SIZE_T -AC_HEADER_TIME -AC_TYPE_UID_T - - -]) diff --git a/php/xmlrpc/libxmlrpc/base64.c b/php/xmlrpc/libxmlrpc/base64.c deleted file mode 100644 index 7788d02..0000000 --- a/php/xmlrpc/libxmlrpc/base64.c +++ /dev/null @@ -1,192 +0,0 @@ -static const char rcsid[] = "#(@) $Id$"; - -/* - - Encode or decode file as MIME base64 (RFC 1341) - - by John Walker - http://www.fourmilab.ch/ - - This program is in the public domain. - -*/ -#include - -/* ENCODE -- Encode binary file into base64. */ -#include -#include - -#include "base64.h" - -static unsigned char dtable[512]; - -void buffer_new(struct buffer_st *b) -{ - b->length = 512; - b->data = malloc(sizeof(char)*(b->length)); - b->data[0] = 0; - b->ptr = b->data; - b->offset = 0; -} - -void buffer_add(struct buffer_st *b, char c) -{ - *(b->ptr++) = c; - b->offset++; - if (b->offset == b->length) { - b->length += 512; - b->data = realloc(b->data, b->length); - b->ptr = b->data + b->offset; - } -} - -void buffer_delete(struct buffer_st *b) -{ - free(b->data); - b->length = 0; - b->offset = 0; - b->ptr = NULL; - b->data = NULL; -} - -void base64_encode(struct buffer_st *b, const char *source, int length) -{ - int i, hiteof = 0; - int offset = 0; - int olen; - - olen = 0; - - buffer_new(b); - - /* Fill dtable with character encodings. */ - - for (i = 0; i < 26; i++) { - dtable[i] = 'A' + i; - dtable[26 + i] = 'a' + i; - } - for (i = 0; i < 10; i++) { - dtable[52 + i] = '0' + i; - } - dtable[62] = '+'; - dtable[63] = '/'; - - while (!hiteof) { - unsigned char igroup[3], ogroup[4]; - int c, n; - - igroup[0] = igroup[1] = igroup[2] = 0; - for (n = 0; n < 3; n++) { - c = *(source++); - offset++; - if (offset > length) { - hiteof = 1; - break; - } - igroup[n] = (unsigned char) c; - } - if (n > 0) { - ogroup[0] = dtable[igroup[0] >> 2]; - ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; - ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; - ogroup[3] = dtable[igroup[2] & 0x3F]; - - /* Replace characters in output stream with "=" pad - characters if fewer than three characters were - read from the end of the input stream. */ - - if (n < 3) { - ogroup[3] = '='; - if (n < 2) { - ogroup[2] = '='; - } - } - for (i = 0; i < 4; i++) { - buffer_add(b, ogroup[i]); - if (!(b->offset % 72)) { - /* buffer_add(b, '\r'); */ - buffer_add(b, '\n'); - } - } - } - } - /* buffer_add(b, '\r'); */ - buffer_add(b, '\n'); -} - -void base64_decode(struct buffer_st *bfr, const char *source, int length) -{ - int i; - int offset = 0; - int endoffile; - int count; - - buffer_new(bfr); - - for (i = 0; i < 255; i++) { - dtable[i] = 0x80; - } - for (i = 'A'; i <= 'Z'; i++) { - dtable[i] = 0 + (i - 'A'); - } - for (i = 'a'; i <= 'z'; i++) { - dtable[i] = 26 + (i - 'a'); - } - for (i = '0'; i <= '9'; i++) { - dtable[i] = 52 + (i - '0'); - } - dtable['+'] = 62; - dtable['/'] = 63; - dtable['='] = 0; - - endoffile = 0; - - /*CONSTANTCONDITION*/ - while (1) { - unsigned char a[4], b[4], o[3]; - - for (i = 0; i < 4; i++) { - int c; - while (1) { - c = *(source++); - offset++; - if (offset > length) endoffile = 1; - if (isspace(c) || c == '\n' || c == '\r') continue; - break; - } - - if (endoffile) { - /* - if (i > 0) { - fprintf(stderr, "Input file incomplete.\n"); - exit(1); - } - */ - return; - } - - if (dtable[c] & 0x80) { - /* - fprintf(stderr, "Offset %i length %i\n", offset, length); - fprintf(stderr, "character '%c:%x:%c' in input file.\n", c, c, dtable[c]); - exit(1); - */ - i--; - continue; - } - a[i] = (unsigned char) c; - b[i] = (unsigned char) dtable[c]; - } - o[0] = (b[0] << 2) | (b[1] >> 4); - o[1] = (b[1] << 4) | (b[2] >> 2); - o[2] = (b[2] << 6) | b[3]; - i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); - count = 0; - while (count < i) { - buffer_add(bfr, o[count++]); - } - if (i < 3) { - return; - } - } -} diff --git a/php/xmlrpc/libxmlrpc/base64.h b/php/xmlrpc/libxmlrpc/base64.h deleted file mode 100644 index 4cf156a..0000000 --- a/php/xmlrpc/libxmlrpc/base64.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - - Encode or decode file as MIME base64 (RFC 1341) - - by John Walker - http://www.fourmilab.ch/ - - This program is in the public domain. - -*/ - - -struct buffer_st { - char *data; - int length; - char *ptr; - int offset; -}; - -void buffer_new(struct buffer_st *b); -void buffer_add(struct buffer_st *b, char c); -void buffer_delete(struct buffer_st *b); - -void base64_encode(struct buffer_st *b, const char *source, int length); -void base64_decode(struct buffer_st *b, const char *source, int length); - -/* -#define DEBUG_MALLOC - */ - -#ifdef DEBUG_MALLOC -void *_malloc_real(size_t s, char *file, int line); -void _free_real(void *p, char *file, int line); - -#define malloc(s) _malloc_real(s,__FILE__,__LINE__) -#define free(p) _free_real(p, __FILE__,__LINE__) -#endif - diff --git a/php/xmlrpc/libxmlrpc/encodings.c b/php/xmlrpc/libxmlrpc/encodings.c deleted file mode 100644 index 1637a09..0000000 --- a/php/xmlrpc/libxmlrpc/encodings.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef PHP_WIN32 -#include -#else -#include -#include -#endif - -static const char rcsid[] = "#(@) $Id$"; - -#include - -#ifdef HAVE_GICONV_H -#include -#else -#include -#endif - -#include "encodings.h" - -static char* convert(const char* src, int src_len, int *new_len, const char* from_enc, const char* to_enc) { - char* outbuf = 0; - - if(src && src_len && from_enc && to_enc) { - size_t outlenleft = src_len; - size_t inlenleft = src_len; - int outlen = src_len; - iconv_t ic = iconv_open(to_enc, from_enc); - char* out_ptr = 0; - - if(ic != (iconv_t)-1) { - size_t st; - outbuf = (char*)malloc(outlen + 1); - - if(outbuf) { - out_ptr = (char*)outbuf; - while(inlenleft) { - st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft); - if(st == -1) { - if(errno == E2BIG) { - int diff = out_ptr - outbuf; - outlen += inlenleft; - outlenleft += inlenleft; - outbuf = (char*)realloc(outbuf, outlen + 1); - if(!outbuf) { - break; - } - out_ptr = outbuf + diff; - } - else { - free(outbuf); - outbuf = 0; - break; - } - } - } - } - iconv_close(ic); - } - outlen -= outlenleft; - - if(new_len) { - *new_len = outbuf ? outlen : 0; - } - if(outbuf) { - outbuf[outlen] = 0; - } - } - return outbuf; -} - -/* returns a new string that must be freed */ -char* utf8_encode(const char *s, int len, int *newlen, const char* encoding) -{ - return convert(s, len, newlen, encoding, "UTF-8"); -} - -/* returns a new string, possibly decoded */ -char* utf8_decode(const char *s, int len, int *newlen, const char* encoding) -{ - return convert(s, len, newlen, "UTF-8", encoding); -} - diff --git a/php/xmlrpc/libxmlrpc/encodings.h b/php/xmlrpc/libxmlrpc/encodings.h deleted file mode 100644 index 486360b..0000000 --- a/php/xmlrpc/libxmlrpc/encodings.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -#ifndef __ENCODINGS__H -#define __ENCODINGS__H - -/* these defines are for legacy purposes. */ -#define encoding_utf_8 "UTF-8" -typedef const char* ENCODING_ID; -#define utf8_get_encoding_id_string(desired_enc) ((const char*)desired_enc) -#define utf8_get_encoding_id_from_string(id_string) ((ENCODING_ID)id_string) - -char* utf8_encode(const char *s, int len, int *newlen, ENCODING_ID encoding); -char* utf8_decode(const char *s, int len, int *newlen, ENCODING_ID encoding); - -#endif /* __ENCODINGS__H */ diff --git a/php/xmlrpc/libxmlrpc/queue.c b/php/xmlrpc/libxmlrpc/queue.c deleted file mode 100644 index 2418738..0000000 --- a/php/xmlrpc/libxmlrpc/queue.c +++ /dev/null @@ -1,982 +0,0 @@ -static const char rcsid[] = "#(@) $Id$"; - -/* - * Date last modified: Jan 2001 - * Modifications by Dan Libby (dan@libby.com), including: - * - various fixes, null checks, etc - * - addition of Q_Iter funcs, macros - */ - - -/*-************************************************************** - * - * File : q.c - * - * Author: Peter Yard [1993.01.02] -- 02 Jan 1993 - * - * Disclaimer: This code is released to the public domain. - * - * Description: - * Generic double ended queue (Deque pronounced DEK) for handling - * any data types, with sorting. - * - * By use of various functions in this module the caller - * can create stacks, queues, lists, doubly linked lists, - * sorted lists, indexed lists. All lists are dynamic. - * - * It is the responsibility of the caller to malloc and free - * memory for insertion into the queue. A pointer to the object - * is used so that not only can any data be used but various kinds - * of data can be pushed on the same queue if one so wished e.g. - * various length string literals mixed with pointers to structures - * or integers etc. - * - * Enhancements: - * A future improvement would be the option of multiple "cursors" - * so that multiple locations could occur in the one queue to allow - * placemarkers and additional flexibility. Perhaps even use queue - * itself to have a list of cursors. - * - * Usage: - * - * /x init queue x/ - * queue q; - * Q_Init(&q); - * - * To create a stack : - * - * Q_PushHead(&q, &mydata1); /x push x/ - * Q_PushHead(&q, &mydata2); - * ..... - * data_ptr = Q_PopHead(&q); /x pop x/ - * ..... - * data_ptr = Q_Head(&q); /x top of stack x/ - * - * To create a FIFO: - * - * Q_PushHead(&q, &mydata1); - * ..... - * data_ptr = Q_PopTail(&q); - * - * To create a double list: - * - * data_ptr = Q_Head(&q); - * .... - * data_ptr = Q_Next(&q); - * data_ptr = Q_Tail(&q); - * if (Q_IsEmpty(&q)) .... - * ..... - * data_ptr = Q_Previous(&q); - * - * To create a sorted list: - * - * Q_PushHead(&q, &mydata1); /x push x/ - * Q_PushHead(&q, &mydata2); - * ..... - * if (!Q_Sort(&q, MyFunction)) - * .. error .. - * - * /x fill in key field of mydata1. - * * NB: Q_Find does linear search - * x/ - * - * if (Q_Find(&q, &mydata1, MyFunction)) - * { - * /x found it, queue cursor now at correct record x/ - * /x can retrieve with x/ - * data_ptr = Q_Get(&q); - * - * /x alter data , write back with x/ - * Q_Put(&q, data_ptr); - * } - * - * /x Search with binary search x/ - * if (Q_Seek(&q, &mydata, MyFunction)) - * /x etc x/ - * - * - ****************************************************************/ - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include "queue.h" - - -static void QuickSort(void *list[], int low, int high, - int (*Comp)(const void *, const void *)); -static int Q_BSearch(queue *q, void *key, - int (*Comp)(const void *, const void *)); - -/* The index: a pointer to pointers */ - -static void **index; -static datanode **posn_index; - - -/*** - * - ** function : Q_Init - * - ** purpose : Initialise queue object and pointers. - * - ** parameters : 'queue' pointer. - * - ** returns : True_ if init successful else False_ - * - ** comments : - ***/ - -int Q_Init(queue *q) -{ - if(q) { - q->head = q->tail = NULL; - q->cursor = q->head; - q->size = 0; - q->sorted = False_; - } - - return True_; -} - -/*** - * - ** function : Q_AtHead - * - ** purpose : tests if cursor is at head of queue - * - ** parameters : 'queue' pointer. - * - ** returns : boolean - True_ is at head else False_ - * - ** comments : - * - ***/ - -int Q_AtHead(queue *q) -{ - return(q && q->cursor == q->head); -} - - -/*** - * - ** function : Q_AtTail - * - ** purpose : boolean test if cursor at tail of queue - * - ** parameters : 'queue' pointer to test. - * - ** returns : True_ or False_ - * - ** comments : - * - ***/ - -int Q_AtTail(queue *q) -{ - return(q && q->cursor == q->tail); -} - - -/*** - * - ** function : Q_IsEmpty - * - ** purpose : test if queue has nothing in it. - * - ** parameters : 'queue' pointer - * - ** returns : True_ if IsEmpty queue, else False_ - * - ** comments : - * - ***/ - -inline int Q_IsEmpty(queue *q) -{ - return(!q || q->size == 0); -} - -/*** - * - ** function : Q_Size - * - ** purpose : return the number of elements in the queue - * - ** parameters : queue pointer - * - ** returns : number of elements - * - ** comments : - * - ***/ - -int Q_Size(queue *q) -{ - return q ? q->size : 0; -} - - -/*** - * - ** function : Q_Head - * - ** purpose : position queue cursor to first element (head) of queue. - * - ** parameters : 'queue' pointer - * - ** returns : pointer to data at head. If queue is IsEmpty returns NULL - * - ** comments : - * - ***/ - -void *Q_Head(queue *q) -{ - if(Q_IsEmpty(q)) - return NULL; - - q->cursor = q->head; - - return q->cursor->data; -} - - -/*** - * - ** function : Q_Tail - * - ** purpose : locate cursor at tail of queue. - * - ** parameters : 'queue' pointer - * - ** returns : pointer to data at tail , if queue IsEmpty returns NULL - * - ** comments : - * - ***/ - -void *Q_Tail(queue *q) -{ - if(Q_IsEmpty(q)) - return NULL; - - q->cursor = q->tail; - - return q->cursor->data; -} - - -/*** - * - ** function : Q_PushHead - * - ** purpose : put a data pointer at the head of the queue - * - ** parameters : 'queue' pointer, void pointer to the data. - * - ** returns : True_ if success else False_ if unable to push data. - * - ** comments : - * - ***/ - -int Q_PushHead(queue *q, void *d) -{ - if(q && d) { - node *n; - datanode *p; - - p = malloc(sizeof(datanode)); - if(p == NULL) - return False_; - - n = q->head; - - q->head = (node*)p; - q->head->prev = NULL; - - if(q->size == 0) { - q->head->next = NULL; - q->tail = q->head; - } - else { - q->head->next = (datanode*)n; - n->prev = q->head; - } - - q->head->data = d; - q->size++; - - q->cursor = q->head; - - q->sorted = False_; - - return True_; - } - return False_; -} - - - -/*** - * - ** function : Q_PushTail - * - ** purpose : put a data element pointer at the tail of the queue - * - ** parameters : queue pointer, pointer to the data - * - ** returns : True_ if data pushed, False_ if data not inserted. - * - ** comments : - * - ***/ - -int Q_PushTail(queue *q, void *d) -{ - if(q && d) { - node *p; - datanode *n; - - n = malloc(sizeof(datanode)); - if(n == NULL) - return False_; - - p = q->tail; - q->tail = (node *)n; - - if(q->size == 0) { - q->tail->prev = NULL; - q->head = q->tail; - } - else { - q->tail->prev = (datanode *)p; - p->next = q->tail; - } - - q->tail->next = NULL; - - q->tail->data = d; - q->cursor = q->tail; - q->size++; - - q->sorted = False_; - - return True_; - } - return False_; -} - - - -/*** - * - ** function : Q_PopHead - * - ** purpose : remove and return the top element at the head of the - * queue. - * - ** parameters : queue pointer - * - ** returns : pointer to data element or NULL if queue is IsEmpty. - * - ** comments : - * - ***/ - -void *Q_PopHead(queue *q) -{ - datanode *n; - void *d; - - if(Q_IsEmpty(q)) - return NULL; - - d = q->head->data; - n = q->head->next; - free(q->head); - - q->size--; - - if(q->size == 0) - q->head = q->tail = q->cursor = NULL; - else { - q->head = (node *)n; - q->head->prev = NULL; - q->cursor = q->head; - } - - q->sorted = False_; - - return d; -} - - -/*** - * - ** function : Q_PopTail - * - ** purpose : remove element from tail of queue and return data. - * - ** parameters : queue pointer - * - ** returns : pointer to data element that was at tail. NULL if queue - * IsEmpty. - * - ** comments : - * - ***/ - -void *Q_PopTail(queue *q) -{ - datanode *p; - void *d; - - if(Q_IsEmpty(q)) - return NULL; - - d = q->tail->data; - p = q->tail->prev; - free(q->tail); - q->size--; - - if(q->size == 0) - q->head = q->tail = q->cursor = NULL; - else { - q->tail = (node *)p; - q->tail->next = NULL; - q->cursor = q->tail; - } - - q->sorted = False_; - - return d; -} - - - -/*** - * - ** function : Q_Next - * - ** purpose : Move to the next element in the queue without popping - * - ** parameters : queue pointer. - * - ** returns : pointer to data element of new element or NULL if end - * of the queue. - * - ** comments : This uses the cursor for the current position. Q_Next - * only moves in the direction from the head of the queue - * to the tail. - ***/ - -void *Q_Next(queue *q) -{ - if(!q) - return NULL; - - if(!q->cursor || q->cursor->next == NULL) - return NULL; - - q->cursor = (node *)q->cursor->next; - - return q->cursor->data ; -} - - - -/*** - * - ** function : Q_Previous - * - ** purpose : Opposite of Q_Next. Move to next element closer to the - * head of the queue. - * - ** parameters : pointer to queue - * - ** returns : pointer to data of new element else NULL if queue IsEmpty - * - ** comments : Makes cursor move towards the head of the queue. - * - ***/ - -void *Q_Previous(queue *q) -{ - if(!q) - return NULL; - - if(q->cursor->prev == NULL) - return NULL; - - q->cursor = (node *)q->cursor->prev; - - return q->cursor->data; -} - - -void *Q_Iter_Del(queue *q, q_iter iter) -{ - void *d; - datanode *n, *p; - - if(!q) - return NULL; - - if(iter == NULL) - return NULL; - - if(iter == (q_iter)q->head) - return Q_PopHead(q); - - if(iter == (q_iter)q->tail) - return Q_PopTail(q); - - n = ((node*)iter)->next; - p = ((node*)iter)->prev; - d = ((node*)iter)->data; - - free(iter); - - if(p) { - p->next = n; - } - if (q->cursor == (node*)iter) { - if (p) { - q->cursor = p; - } else { - q->cursor = n; - } - } - - - if (n != NULL) { - n->prev = p; - } - - q->size--; - - q->sorted = False_; - - return d; -} - - - -/*** - * - ** function : Q_DelCur - * - ** purpose : Delete the current queue element as pointed to by - * the cursor. - * - ** parameters : queue pointer - * - ** returns : pointer to data element. - * - ** comments : WARNING! It is the responsibility of the caller to - * free any memory. Queue cannot distinguish between - * pointers to literals and malloced memory. - * - ***/ - -void *Q_DelCur(queue* q) { - if(q) { - return Q_Iter_Del(q, (q_iter)q->cursor); - } - return 0; -} - - -/*** - * - ** function : Q_Destroy - * - ** purpose : Free all queue resources - * - ** parameters : queue pointer - * - ** returns : null. - * - ** comments : WARNING! It is the responsibility of the caller to - * free any memory. Queue cannot distinguish between - * pointers to literals and malloced memory. - * - ***/ - -void Q_Destroy(queue *q) -{ - while(!Q_IsEmpty(q)) { - Q_PopHead(q); - } -} - - -/*** - * - ** function : Q_Get - * - ** purpose : get the pointer to the data at the cursor location - * - ** parameters : queue pointer - * - ** returns : data element pointer - * - ** comments : - * - ***/ - -void *Q_Get(queue *q) -{ - if(!q) - return NULL; - - if(q->cursor == NULL) - return NULL; - return q->cursor->data; -} - - - -/*** - * - ** function : Q_Put - * - ** purpose : replace pointer to data with new pointer to data. - * - ** parameters : queue pointer, data pointer - * - ** returns : boolean- True_ if successful, False_ if cursor at NULL - * - ** comments : - * - ***/ - -int Q_Put(queue *q, void *data) -{ - if(q && data) { - if(q->cursor == NULL) - return False_; - - q->cursor->data = data; - return True_; - } - return False_; -} - - -/*** - * - ** function : Q_Find - * - ** purpose : Linear search of queue for match with key in *data - * - ** parameters : queue pointer q, data pointer with data containing key - * comparison function here called Comp. - * - ** returns : True_ if found , False_ if not in queue. - * - ** comments : Useful for small queues that are constantly changing - * and would otherwise need constant sorting with the - * Q_Seek function. - * For description of Comp see Q_Sort. - * Queue cursor left on position found item else at end. - * - ***/ - -int Q_Find(queue *q, void *data, - int (*Comp)(const void *, const void *)) -{ - void *d; - - if (q == NULL) { - return False_; - } - - d = Q_Head(q); - do { - if(Comp(d, data) == 0) - return True_; - d = Q_Next(q); - } while(!Q_AtTail(q)); - - if(Comp(d, data) == 0) - return True_; - - return False_; -} - -/*======== Sorted Queue and Index functions ========= */ - - -static void QuickSort(void *list[], int low, int high, - int (*Comp)(const void *, const void *)) -{ - int flag = 1, i, j; - void *key, *temp; - - if(low < high) { - i = low; - j = high + 1; - - key = list[ low ]; - - while(flag) { - i++; - while(Comp(list[i], key) < 0) - i++; - - j--; - while(Comp(list[j], key) > 0) - j--; - - if(i < j) { - temp = list[i]; - list[i] = list[j]; - list[j] = temp; - } - else flag = 0; - } - - temp = list[low]; - list[low] = list[j]; - list[j] = temp; - - QuickSort(list, low, j-1, Comp); - QuickSort(list, j+1, high, Comp); - } -} - - -/*** - * - ** function : Q_Sort - * - ** purpose : sort the queue and allow index style access. - * - ** parameters : queue pointer, comparison function compatible with - * with 'qsort'. - * - ** returns : True_ if sort succeeded. False_ if error occurred. - * - ** comments : Comp function supplied by caller must return - * -1 if data1 < data2 - * 0 if data1 == data2 - * +1 if data1 > data2 - * - * for Comp(data1, data2) - * - * If queue is already sorted it frees the memory of the - * old index and starts again. - * - ***/ - -int Q_Sort(queue *q, int (*Comp)(const void *, const void *)) -{ - int i; - void *d; - datanode *dn; - - /* if already sorted free memory for tag array */ - - if(q->sorted) { - free(index); - free(posn_index); - q->sorted = False_; - } - - /* Now allocate memory of array, array of pointers */ - - index = malloc(q->size * sizeof(q->cursor->data)); - if(index == NULL) - return False_; - - posn_index = malloc(q->size * sizeof(q->cursor)); - if(posn_index == NULL) { - free(index); - return False_; - } - - /* Walk queue putting pointers into array */ - - d = Q_Head(q); - for(i=0; i < q->size; i++) { - index[i] = d; - posn_index[i] = q->cursor; - d = Q_Next(q); - } - - /* Now sort the index */ - - QuickSort(index, 0, q->size - 1, Comp); - - /* Rearrange the actual queue into correct order */ - - dn = q->head; - i = 0; - while(dn != NULL) { - dn->data = index[i++]; - dn = dn->next; - } - - /* Re-position to original element */ - - if(d != NULL) - Q_Find(q, d, Comp); - else Q_Head(q); - - q->sorted = True_; - - return True_; -} - - -/*** - * - ** function : Q_BSearch - * - ** purpose : binary search of queue index for node containing key - * - ** parameters : queue pointer 'q', data pointer of key 'key', - * Comp comparison function. - * - ** returns : integer index into array of node pointers, - * or -1 if not found. - * - ** comments : see Q_Sort for description of 'Comp' function. - * - ***/ - -static int Q_BSearch( queue *q, void *key, - int (*Comp)(const void *, const void*)) -{ - int low, mid, hi, val; - - low = 0; - hi = q->size - 1; - - while(low <= hi) { - mid = (low + hi) / 2; - val = Comp(key, index[ mid ]); - - if(val < 0) - hi = mid - 1; - - else if(val > 0) - low = mid + 1; - - else /* Success */ - return mid; - } - - /* Not Found */ - - return -1; -} - - -/*** - * - ** function : Q_Seek - * - ** purpose : use index to locate data according to key in 'data' - * - ** parameters : queue pointer 'q', data pointer 'data', Comp comparison - * function. - * - ** returns : pointer to data or NULL if could not find it or could - * not sort queue. - * - ** comments : see Q_Sort for description of 'Comp' function. - * - ***/ - -void *Q_Seek(queue *q, void *data, int (*Comp)(const void *, const void *)) -{ - int idx; - - if (q == NULL) { - return NULL; - } - - if(!q->sorted) { - if(!Q_Sort(q, Comp)) - return NULL; - } - - idx = Q_BSearch(q, data, Comp); - - if(idx < 0) - return NULL; - - q->cursor = posn_index[idx]; - - return index[idx]; -} - - - -/*** - * - ** function : Q_Insert - * - ** purpose : Insert an element into an indexed queue - * - ** parameters : queue pointer 'q', data pointer 'data', Comp comparison - * function. - * - ** returns : pointer to data or NULL if could not find it or could - * not sort queue. - * - ** comments : see Q_Sort for description of 'Comp' function. - * WARNING! This code can be very slow since each new - * element means a new Q_Sort. Should only be used for - * the insertion of the odd element ,not the piecemeal - * building of an entire queue. - ***/ - -int Q_Insert(queue *q, void *data, int (*Comp)(const void *, const void *)) -{ - if (q == NULL) { - return False_; - } - - Q_PushHead(q, data); - - if(!Q_Sort(q, Comp)) - return False_; - - return True_; -} - -/* read only funcs for iterating through queue. above funcs modify queue */ -q_iter Q_Iter_Head(queue *q) { - return q ? (q_iter)q->head : NULL; -} - -q_iter Q_Iter_Tail(queue *q) { - return q ? (q_iter)q->tail : NULL; -} - -q_iter Q_Iter_Next(q_iter qi) { - return qi ? (q_iter)((node*)qi)->next : NULL; -} - -q_iter Q_Iter_Prev(q_iter qi) { - return qi ? (q_iter)((node*)qi)->prev : NULL; -} - -void * Q_Iter_Get(q_iter qi) { - return qi ? ((node*)qi)->data : NULL; -} - -int Q_Iter_Put(q_iter qi, void* data) { - if(qi) { - ((node*)qi)->data = data; - return True_; - } - return False_; -} diff --git a/php/xmlrpc/libxmlrpc/queue.h b/php/xmlrpc/libxmlrpc/queue.h deleted file mode 100644 index be73f6d..0000000 --- a/php/xmlrpc/libxmlrpc/queue.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Date last modified: Jan 2001 - * Modifications by Dan Libby (dan@libby.com), including: - * - various fixes, null checks, etc - * - addition of Q_Iter funcs, macros - */ - -/* - * File : q.h - * - * Peter Yard 02 Jan 1993. - * - * Disclaimer: This code is released to the public domain. - */ - -#ifndef Q__H -#define Q__H - -#ifndef False_ - #define False_ 0 -#endif - -#ifndef True_ - #define True_ 1 -#endif - -typedef struct nodeptr datanode; - -typedef struct nodeptr { - void *data ; - datanode *prev, *next ; -} node ; - -/* For external use with Q_Iter* funcs */ -typedef struct nodeptr* q_iter; - -typedef struct { - node *head, *tail, *cursor; - int size, sorted, item_deleted; -} queue; - -typedef struct { - void *dataptr; - node *loc ; -} index_elt ; - - -int Q_Init(queue *q); -void Q_Destroy(queue *q); -int Q_IsEmpty(queue *q); -int Q_Size(queue *q); -int Q_AtHead(queue *q); -int Q_AtTail(queue *q); -int Q_PushHead(queue *q, void *d); -int Q_PushTail(queue *q, void *d); -void *Q_Head(queue *q); -void *Q_Tail(queue *q); -void *Q_PopHead(queue *q); -void *Q_PopTail(queue *q); -void *Q_Next(queue *q); -void *Q_Previous(queue *q); -void *Q_DelCur(queue *q); -void *Q_Get(queue *q); -int Q_Put(queue *q, void *data); -int Q_Sort(queue *q, int (*Comp)(const void *, const void *)); -int Q_Find(queue *q, void *data, - int (*Comp)(const void *, const void *)); -void *Q_Seek(queue *q, void *data, - int (*Comp)(const void *, const void *)); -int Q_Insert(queue *q, void *data, - int (*Comp)(const void *, const void *)); - -/* read only funcs for iterating through queue. above funcs modify queue */ -q_iter Q_Iter_Head(queue *q); -q_iter Q_Iter_Tail(queue *q); -q_iter Q_Iter_Next(q_iter qi); -q_iter Q_Iter_Prev(q_iter qi); -void* Q_Iter_Get(q_iter qi); -int Q_Iter_Put(q_iter qi, void* data); /* not read only! here for completeness. */ -void* Q_Iter_Del(queue *q, q_iter iter); /* not read only! here for completeness. */ - -/* Fast (macro'd) versions of above */ -#define Q_Iter_Head_F(q) (q ? (q_iter)((queue*)q)->head : NULL) -#define Q_Iter_Tail_F(q) (q ? (q_iter)((queue*)q)->tail : NULL) -#define Q_Iter_Next_F(qi) (qi ? (q_iter)((node*)qi)->next : NULL) -#define Q_Iter_Prev_F(qi) (qi ? (q_iter)((node*)qi)->prev : NULL) -#define Q_Iter_Get_F(qi) (qi ? ((node*)qi)->data : NULL) - -#endif /* Q__H */ diff --git a/php/xmlrpc/libxmlrpc/simplestring.c b/php/xmlrpc/libxmlrpc/simplestring.c deleted file mode 100644 index be2aba5..0000000 --- a/php/xmlrpc/libxmlrpc/simplestring.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - - -#define SIMPLESTRING_INCR 32 - -/****h* ABOUT/simplestring - * NAME - * simplestring - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * CREATION DATE - * 06/2000 - * HISTORY - * $Log: simplestring.c,v $ - * Revision 1.4 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.3 2002/08/22 01:25:50 sniper - * kill some compile warnings - * - * Revision 1.2 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.4 2002/02/13 20:58:50 danda - * patch to make source more windows friendly, contributed by Jeff Lawson - * - * Revision 1.3 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 10/15/2000 -- danda -- adding robodoc documentation - * PORTABILITY - * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just - * about anything with minor mods. - * NOTES - * This code was written primarily for xmlrpc, but has found some other uses. - * - * simplestring is, as the name implies, a simple API for dealing with C strings. - * Why would I write yet another string API? Because I couldn't find any that were - * a) free / GPL, b) simple/lightweight, c) fast, not doing unneccesary strlens all - * over the place. So. It is simple, and it seems to work, and it is pretty fast. - * - * Oh, and it is also binary safe, ie it can handle strings with embedded NULLs, - * so long as the real length is passed in. - * - * And the masses rejoiced. - * - * BUGS - * there must be some. - ******/ - -#include -#include -#include "simplestring.h" - -#define my_free(thing) if(thing) {free(thing); thing = 0;} - -/*----------------------** -* Begin String Functions * -*-----------------------*/ - -/****f* FUNC/simplestring_init - * NAME - * simplestring_init - * SYNOPSIS - * void simplestring_init(simplestring* string) - * FUNCTION - * initialize string - * INPUTS - * string - pointer to a simplestring struct that will be initialized - * RESULT - * void - * NOTES - * SEE ALSO - * simplestring_free () - * simplestring_clear () - * SOURCE - */ -void simplestring_init(simplestring* string) { - memset(string, 0, sizeof(simplestring)); -} -/******/ - -static void simplestring_init_str(simplestring* string) { - string->str = (char*)malloc(SIMPLESTRING_INCR); - if(string->str) { - string->str[0] = 0; - string->len = 0; - string->size = SIMPLESTRING_INCR; - } - else { - string->size = 0; - } -} - -/****f* FUNC/simplestring_clear - * NAME - * simplestring_clear - * SYNOPSIS - * void simplestring_clear(simplestring* string) - * FUNCTION - * clears contents of a string - * INPUTS - * string - the string value to clear - * RESULT - * void - * NOTES - * This function is very fast as it does not de-allocate any memory. - * SEE ALSO - * - * SOURCE - */ -void simplestring_clear(simplestring* string) { - if(string->str) { - string->str[0] = 0; - } - string->len = 0; -} -/******/ - -/****f* FUNC/simplestring_free - * NAME - * simplestring_free - * SYNOPSIS - * void simplestring_free(simplestring* string) - * FUNCTION - * frees contents of a string, if any. Does *not* free the simplestring struct itself. - * INPUTS - * string - value containing string to be free'd - * RESULT - * void - * NOTES - * caller is responsible for allocating and freeing simplestring* struct itself. - * SEE ALSO - * simplestring_init () - * SOURCE - */ -void simplestring_free(simplestring* string) { - if(string && string->str) { - my_free(string->str); - string->len = 0; - } -} -/******/ - -/****f* FUNC/simplestring_addn - * NAME - * simplestring_addn - * SYNOPSIS - * void simplestring_addn(simplestring* string, const char* add, int add_len) - * FUNCTION - * copies n characters from source to target string - * INPUTS - * target - target string - * source - source string - * add_len - number of characters to copy - * RESULT - * void - * NOTES - * SEE ALSO - * simplestring_add () - * SOURCE - */ -void simplestring_addn(simplestring* target, const char* source, int add_len) { - if(target && source) { - if(!target->str) { - simplestring_init_str(target); - } - if(target->len + add_len + 1 > target->size) { - /* newsize is current length + new length */ - int newsize = target->len + add_len + 1; - int incr = target->size * 2; - - /* align to SIMPLESTRING_INCR increments */ - newsize = newsize - (newsize % incr) + incr; - target->str = (char*)realloc(target->str, newsize); - - target->size = target->str ? newsize : 0; - } - - if(target->str) { - if(add_len) { - memcpy(target->str + target->len, source, add_len); - } - target->len += add_len; - target->str[target->len] = 0; /* null terminate */ - } - } -} -/******/ - -/****f* FUNC/simplestring_add - * NAME - * simplestring_add - * SYNOPSIS - * void simplestring_add(simplestring* string, const char* add) - * FUNCTION - * appends a string of unknown length from source to target - * INPUTS - * target - the target string to append to - * source - the source string of unknown length - * RESULT - * void - * NOTES - * SEE ALSO - * simplestring_addn () - * SOURCE - */ -void simplestring_add(simplestring* target, const char* source) { - if(target && source) { - simplestring_addn(target, source, strlen(source)); - } -} -/******/ - - -/*---------------------- -* End String Functions * -*--------------------**/ diff --git a/php/xmlrpc/libxmlrpc/simplestring.h b/php/xmlrpc/libxmlrpc/simplestring.h deleted file mode 100644 index c5d98cf..0000000 --- a/php/xmlrpc/libxmlrpc/simplestring.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifndef __SIMPLESTRING_H__ - #define __SIMPLESTRING_H__ - -/*-******************************** -* begin simplestring header stuff * -**********************************/ - -#ifdef __cplusplus -extern "C" { -#endif - - /****s* struct/simplestring - * NAME - * simplestring - * NOTES - * represents a string efficiently for fast appending, etc. - * SOURCE - */ -typedef struct _simplestring { - char* str; /* string buf */ - int len; /* length of string/buf */ - int size; /* size of allocated buffer */ -} simplestring; -/******/ - -#ifndef NULL - #define NULL 0 -#endif - -void simplestring_init(simplestring* string); -void simplestring_clear(simplestring* string); -void simplestring_free(simplestring* string); -void simplestring_add(simplestring* string, const char* add); -void simplestring_addn(simplestring* string, const char* add, int add_len); - -#ifdef __cplusplus -} -#endif - -/*-****************************** -* end simplestring header stuff * -********************************/ - -#endif /* __SIMPLESTRING_H__ */ diff --git a/php/xmlrpc/libxmlrpc/system_methods.c b/php/xmlrpc/libxmlrpc/system_methods.c deleted file mode 100644 index c3c2b88..0000000 --- a/php/xmlrpc/libxmlrpc/system_methods.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -/****h* ABOUT/system_methods - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * HISTORY - * $Log: system_methods.c,v $ - * Revision 1.2 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.7 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 4/28/2001 -- danda -- adding system.multicall and separating out system methods. - * TODO - * NOTES - *******/ - - -#include "queue.h" -#include "xmlrpc.h" -#include "xmlrpc_private.h" -#include "xmlrpc_introspection_private.h" -#include "system_methods_private.h" -#include -#include -#include - - -static const char* xsm_introspection_xml = -"" - -"" - "" - - "" - "value identifier" - "value's xmlrpc or user-defined type" - "value's textual description " - "true if value is optional, else it is required " - "a child of this element. n/a for scalar types " - "" - - "" - "" - "" - - "" - "" - "" - - - "" - - "" - - "" - "" - "Dan Libby" - "fully describes the methods and types implemented by this XML-RPC server." - "1.1" - "" - "" - "" - "" - "a valid method name" - "" - "" - "" - "" - "" - "" - "method name" - "method version" - "method author" - "method purpose" - "" - "" - "parameter list" - "return value list" - "" - "" - "list of known bugs" - "list of possible errors and error codes" - "list of examples" - "list of modifications" - "list of notes" - "see also. list of related methods" - "list of unimplemented features" - "" - "" - "" - "a type description" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" - "" - "Dan Libby" - "enumerates the methods implemented by this XML-RPC server." - "1.0" - "" - "" - "" - "" - "name of a method implemented by the server." - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" - "" - "Dan Libby" - "provides documentation string for a single method" - "1.0" - "" - "" - "" - "name of the method for which documentation is desired" - "" - "" - "help text if defined for the method passed, otherwise an empty string" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" - "" - "Dan Libby" - "provides 1 or more signatures for a single method" - "1.0" - "" - "" - "" - "name of the method for which documentation is desired" - "" - "" - "" - "" - "a string indicating the xmlrpc type of a value. one of: string, int, double, base64, datetime, array, struct" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" - "" - "Dan Libby" - "executes multiple methods in sequence and returns the results" - "1.0" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" - "" - "Dan Libby" - "returns a list of capabilities supported by this server" - "1.0" - "spec url: http://groups.yahoo.com/group/xml-rpc/message/2897" - "" - "" - "" - "" - "" - "www address of the specification defining this capability" - "version of the spec that this server's implementation conforms to" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - - "" -""; - - -/* forward declarations for static (non public, non api) funcs */ -static XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); -static XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); - -/*-******************* -* System Methods API * -*********************/ - -static void xsm_lazy_doc_methods_cb(XMLRPC_SERVER server, void* userData) { - XMLRPC_VALUE xDesc = XMLRPC_IntrospectionCreateDescription(xsm_introspection_xml, NULL); - XMLRPC_ServerAddIntrospectionData(server, xDesc); - XMLRPC_CleanupValue(xDesc); -} - -void xsm_register(XMLRPC_SERVER server) { - xi_register_system_methods(server); - - XMLRPC_ServerRegisterMethod(server, xsm_token_system_multicall, xsm_system_multicall_cb); - XMLRPC_ServerRegisterMethod(server, xsm_token_system_get_capabilities, xsm_system_get_capabilities_cb); - - /* callback for documentation generation should it be requested */ - XMLRPC_ServerRegisterIntrospectionCallback(server, xsm_lazy_doc_methods_cb); -} - -XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - XMLRPC_VALUE xArray = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); - XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_array); - - if (xArray) { - XMLRPC_VALUE xMethodIter = XMLRPC_VectorRewind(xArray); - - while (xMethodIter) { - XMLRPC_REQUEST request = XMLRPC_RequestNew(); - if(request) { - const char* methodName = XMLRPC_VectorGetStringWithID(xMethodIter, "methodName"); - XMLRPC_VALUE params = XMLRPC_VectorGetValueWithID(xMethodIter, "params"); - - if(methodName && params) { - XMLRPC_VALUE xRandomArray = XMLRPC_CreateVector(0, xmlrpc_vector_array); - XMLRPC_RequestSetMethodName(request, methodName); - XMLRPC_RequestSetData(request, params); - XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); - - XMLRPC_AddValueToVector(xRandomArray, - XMLRPC_ServerCallMethod(server, request, userData)); - - XMLRPC_AddValueToVector(xReturn, xRandomArray); - } - XMLRPC_RequestFree(request, 1); - } - xMethodIter = XMLRPC_VectorNext(xArray); - } - } - return xReturn; -} - - -XMLRPC_VALUE xsm_system_get_capabilities_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_struct); - XMLRPC_VALUE xFaults = XMLRPC_CreateVector("faults_interop", xmlrpc_vector_struct); - XMLRPC_VALUE xIntro = XMLRPC_CreateVector("introspection", xmlrpc_vector_struct); - - /* support for fault spec */ - XMLRPC_VectorAppendString(xFaults, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php", 0); - XMLRPC_VectorAppendInt(xFaults, "specVersion", 20010516); - - /* support for introspection spec */ - XMLRPC_VectorAppendString(xIntro, "specURL", "http://xmlrpc-epi.sourceforge.net/specs/rfc.introspection.php", 0); - XMLRPC_VectorAppendInt(xIntro, "specVersion", 20010516); - - XMLRPC_AddValuesToVector(xReturn, - xFaults, - xIntro, - NULL); - - return xReturn; - -} - -/*-*********************** -* End System Methods API * -*************************/ - - - diff --git a/php/xmlrpc/libxmlrpc/system_methods_private.h b/php/xmlrpc/libxmlrpc/system_methods_private.h deleted file mode 100644 index 72408fd..0000000 --- a/php/xmlrpc/libxmlrpc/system_methods_private.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Dan Libby, Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* IMPORTANT! - * - * only non-public things should be in this file. It is fine for any .c file - * in xmlrpc/src to include it, but users of the public API should never - * include it, and thus *.h files that are part of the public API should - * never include it, or they would break if this file is not present. - */ - - -#ifndef __SYSTEM_METHODS_PRIVATE_H -/* - * Avoid include redundancy. - */ -#define __SYSTEM_METHODS_PRIVATE_H - -/*---------------------------------------------------------------------------- - * system_methods_private.h - * - * Purpose: - * define non-public system.* methods - * Comments: - * xsm = xmlrpc system methods - */ - -/*---------------------------------------------------------------------------- - * Constants - */ -#define xsm_token_system_multicall "system.multiCall" -#define xsm_token_system_get_capabilities "system.getCapabilities" - - -/*---------------------------------------------------------------------------- - * Includes - */ - -/*---------------------------------------------------------------------------- - * Structures - */ - -/*---------------------------------------------------------------------------- - * Globals - */ - -/*---------------------------------------------------------------------------- - * Functions - */ -void xsm_register(XMLRPC_SERVER server); -int xsm_is_system_method(XMLRPC_Callback cb); - -/*---------------------------------------------------------------------------- - * Macros - */ - - -#endif /* __SYSTEM_METHODS_PRIVATE_H */ - - - - diff --git a/php/xmlrpc/libxmlrpc/xml_element.c b/php/xmlrpc/libxmlrpc/xml_element.c deleted file mode 100644 index ae30838..0000000 --- a/php/xmlrpc/libxmlrpc/xml_element.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - - - -/****h* ABOUT/xml_element - * NAME - * xml_element - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * CREATION DATE - * 06/2000 - * HISTORY - * $Log: xml_element.c,v $ - * Revision 1.6 2004/06/01 20:16:06 iliaa - * Fixed bug #28597 (xmlrpc_encode_request() incorrectly encodes chars in - * 200-210 range). - * Patch by: fernando dot nemec at folha dot com dot br - * - * Revision 1.5 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.4 2002/11/26 23:01:16 fmk - * removing unused variables - * - * Revision 1.3 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.9 2002/07/03 20:54:30 danda - * root element should not have a parent. patch from anon SF user - * - * Revision 1.8 2002/05/23 17:46:51 danda - * patch from mukund - fix non utf-8 encoding conversions - * - * Revision 1.7 2002/02/13 20:58:50 danda - * patch to make source more windows friendly, contributed by Jeff Lawson - * - * Revision 1.6 2002/01/08 01:06:55 danda - * enable format for parsers that are very picky. - * - * Revision 1.5 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 10/15/2000 -- danda -- adding robodoc documentation - * TODO - * Nicer external API. Get rid of macros. Make opaque types, etc. - * PORTABILITY - * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just - * about anything with minor mods. - * NOTES - * This code incorporates ideas from expat-ensor from http://xml.ensor.org. - * - * It was coded primarily to act as a go-between for expat and xmlrpc. To this - * end, it stores xml elements, their sub-elements, and their attributes in an - * in-memory tree. When expat is done parsing, the tree can be walked, thus - * retrieving the values. The code can also be used to build a tree via API then - * write out the tree to a buffer, thus "serializing" the xml. - * - * It turns out this is useful for other purposes, such as parsing config files. - * YMMV. - * - * Some Features: - * - output option for xml escaping data. Choices include no escaping, entity escaping, - * or CDATA sections. - * - output option for character encoding. Defaults to (none) utf-8. - * - output option for verbosity/readability. ultra-compact, newlines, pretty/level indented. - * - * BUGS - * there must be some. - ******/ - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include - -#include "xml_element.h" -#include "queue.h" -#include "expat.h" -#include "encodings.h" - -#define my_free(thing) if(thing) {free(thing); thing = NULL;} - -#define XML_DECL_START "" -#define XML_DECL_END_LEN sizeof(XML_DECL_END) - 1 -#define START_TOKEN_BEGIN "<" -#define START_TOKEN_BEGIN_LEN sizeof(START_TOKEN_BEGIN) - 1 -#define START_TOKEN_END ">" -#define START_TOKEN_END_LEN sizeof(START_TOKEN_END) - 1 -#define EMPTY_START_TOKEN_END "/>" -#define EMPTY_START_TOKEN_END_LEN sizeof(EMPTY_START_TOKEN_END) - 1 -#define END_TOKEN_BEGIN "" -#define END_TOKEN_END_LEN sizeof(END_TOKEN_END) - 1 -#define ATTR_DELIMITER "\"" -#define ATTR_DELIMITER_LEN sizeof(ATTR_DELIMITER) - 1 -#define CDATA_BEGIN "" -#define CDATA_END_LEN sizeof(CDATA_END) - 1 -#define EQUALS "=" -#define EQUALS_LEN sizeof(EQUALS) - 1 -#define WHITESPACE " " -#define WHITESPACE_LEN sizeof(WHITESPACE) - 1 -#define NEWLINE "\n" -#define NEWLINE_LEN sizeof(NEWLINE) - 1 -#define MAX_VAL_BUF 144 -#define SCALAR_STR "SCALAR" -#define SCALAR_STR_LEN sizeof(SCALAR_STR) - 1 -#define VECTOR_STR "VECTOR" -#define VECTOR_STR_LEN sizeof(VECTOR_STR) - 1 -#define RESPONSE_STR "RESPONSE" -#define RESPONSE_STR_LEN sizeof(RESPONSE_STR) - 1 - - -/*----------------------------- -- Begin xml_element Functions - ------------------------------*/ - -/****f* xml_element/xml_elem_free_non_recurse - * NAME - * xml_elem_free_non_recurse - * SYNOPSIS - * void xml_elem_free_non_recurse(xml_element* root) - * FUNCTION - * free a single xml element. child elements will not be freed. - * INPUTS - * root - the element to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free_non_recurse(xml_element* root) { - if(root) { - xml_element_attr* attrs = Q_Head(&root->attrs); - while(attrs) { - my_free(attrs->key); - my_free(attrs->val); - my_free(attrs); - attrs = Q_Next(&root->attrs); - } - - Q_Destroy(&root->children); - Q_Destroy(&root->attrs); - if (root->name) { - free((char *)root->name); - root->name = NULL; - } - simplestring_free(&root->text); - my_free(root); - } -} -/******/ - -/****f* xml_element/xml_elem_free - * NAME - * xml_elem_free - * SYNOPSIS - * void xml_elem_free(xml_element* root) - * FUNCTION - * free an xml element and all of its child elements - * INPUTS - * root - the root of an xml tree you would like to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free_non_recurse () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free(xml_element* root) { - if(root) { - xml_element* kids = Q_Head(&root->children); - while(kids) { - xml_elem_free(kids); - kids = Q_Next(&root->children); - } - xml_elem_free_non_recurse(root); - } -} -/******/ - -/****f* xml_element/xml_elem_new - * NAME - * xml_elem_new - * SYNOPSIS - * xml_element* xml_elem_new() - * FUNCTION - * allocates and initializes a new xml_element - * INPUTS - * none - * RESULT - * xml_element* or NULL. NULL indicates an out-of-memory condition. - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_free_non_recurse () - * SOURCE - */ -xml_element* xml_elem_new() { - xml_element* elem = calloc(1, sizeof(xml_element)); - if(elem) { - Q_Init(&elem->children); - Q_Init(&elem->attrs); - simplestring_init(&elem->text); - - /* init empty string in case we don't find any char data */ - simplestring_addn(&elem->text, "", 0); - } - return elem; -} -/******/ - -static int xml_elem_writefunc(int (*fptr)(void *data, const char *text, int size), const char *text, void *data, int len) -{ - return fptr && text ? fptr(data, text, len ? len : strlen(text)) : 0; -} - - - -static int create_xml_escape(char *pString, unsigned char c) -{ - int counter = 0; - - pString[counter++] = '&'; - pString[counter++] = '#'; - if(c >= 100) { - pString[counter++] = c / 100 + '0'; - c = c % 100; - } - pString[counter++] = c / 10 + '0'; - c = c % 10; - - pString[counter++] = c + '0'; - pString[counter++] = ';'; - return counter; -} - -#define non_ascii(c) (c > 127) -#define non_print(c) (!isprint(c)) -#define markup(c) (c == '&' || c == '\"' || c == '>' || c == '<') -#define entity_length(c) ( (c >= 100) ? 3 : ((c >= 10) ? 2 : 1) ) + 3; /* "&#" + c + ";" */ - -/* - * xml_elem_entity_escape - * - * Purpose: - * escape reserved xml chars and non utf-8 chars as xml entities - * Comments: - * The return value may be a new string, or null if no - * conversion was performed. In the latter case, *newlen will - * be 0. - * Flags (to escape) - * xml_elem_no_escaping = 0x000, - * xml_elem_entity_escaping = 0x002, // escape xml special chars as entities - * xml_elem_non_ascii_escaping = 0x008, // escape chars above 127 - * xml_elem_cdata_escaping = 0x010, // wrap in cdata - */ -static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, XML_ELEM_ESCAPING flags) { - char *pRetval = 0; - int iNewBufLen=0; - -#define should_escape(c, flag) ( ((flag & xml_elem_markup_escaping) && markup(c)) || \ - ((flag & xml_elem_non_ascii_escaping) && non_ascii(c)) || \ - ((flag & xml_elem_non_print_escaping) && non_print(c)) ) - - if(buf && *buf) { - const unsigned char *bufcopy; - char *NewBuffer; - int ToBeXmlEscaped=0; - int iLength; - bufcopy = buf; - iLength= old_len ? old_len : strlen(buf); - while(*bufcopy) { - if( should_escape(*bufcopy, flags) ) { - /* the length will increase by length of xml escape - the character length */ - iLength += entity_length(*bufcopy); - ToBeXmlEscaped=1; - } - bufcopy++; - } - - if(ToBeXmlEscaped) { - - NewBuffer= malloc(iLength+1); - if(NewBuffer) { - bufcopy=buf; - while(*bufcopy) { - if(should_escape(*bufcopy, flags)) { - iNewBufLen += create_xml_escape(NewBuffer+iNewBufLen,*bufcopy); - } - else { - NewBuffer[iNewBufLen++]=*bufcopy; - } - bufcopy++; - } - NewBuffer[iNewBufLen] = 0; - pRetval = NewBuffer; - } - } - } - - if(newlen) { - *newlen = iNewBufLen; - } - - return pRetval; -} - - -static void xml_element_serialize(xml_element *el, int (*fptr)(void *data, const char *text, int size), void *data, XML_ELEM_OUTPUT_OPTIONS options, int depth) -{ - int i; - static STRUCT_XML_ELEM_OUTPUT_OPTIONS default_opts = {xml_elem_pretty, xml_elem_markup_escaping | xml_elem_non_print_escaping, XML_DECL_ENCODING_DEFAULT}; - static char whitespace[] = " " - " " - " "; - depth++; - - if(!el) { - fprintf(stderr, "Nothing to write\n"); - return; - } - if(!options) { - options = &default_opts; - } - - /* print xml declaration if at root level */ - if(depth == 1) { - xml_elem_writefunc(fptr, XML_DECL_START, data, XML_DECL_START_LEN); - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_VERSION, data, XML_DECL_VERSION_LEN); - if(options->encoding && *options->encoding) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_ENCODING_ATTR, data, XML_DECL_ENCODING_ATTR_LEN); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, options->encoding, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - } - xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN); - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - /* begin element */ - xml_elem_writefunc(fptr,START_TOKEN_BEGIN, data, START_TOKEN_BEGIN_LEN); - if(el->name) { - xml_elem_writefunc(fptr, el->name, data, 0); - - /* write attrs, if any */ - if(Q_Size(&el->attrs)) { - xml_element_attr* iter = Q_Head(&el->attrs); - while( iter ) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, iter->key, data, 0); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, iter->val, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - - iter = Q_Next(&el->attrs); - } - } - } - else { - xml_elem_writefunc(fptr, "None", data, 0); - } - /* if no text and no children, use abbreviated form, eg: */ - if(!el->text.len && !Q_Size(&el->children)) { - xml_elem_writefunc(fptr, EMPTY_START_TOKEN_END, data, EMPTY_START_TOKEN_END_LEN); - } - /* otherwise, print element contents */ - else { - xml_elem_writefunc(fptr, START_TOKEN_END, data, START_TOKEN_END_LEN); - - /* print text, if any */ - if(el->text.len) { - char* escaped_str = el->text.str; - int buflen = el->text.len; - - if(options->escaping && options->escaping != xml_elem_cdata_escaping) { - escaped_str = xml_elem_entity_escape(el->text.str, buflen, &buflen, options->escaping ); - if(!escaped_str) { - escaped_str = el->text.str; - } - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_BEGIN, data, CDATA_BEGIN_LEN); - } - - xml_elem_writefunc(fptr, escaped_str, data, buflen); - - if(escaped_str != el->text.str) { - my_free(escaped_str); - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_END, data, CDATA_END_LEN); - } - } - /* no text, so print child elems */ - else { - xml_element *kids = Q_Head(&el->children); - i = 0; - while( kids ) { - if(i++ == 0) { - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - xml_element_serialize(kids, fptr, data, options, depth); - kids = Q_Next(&el->children); - } - if(i) { - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - } - } - - xml_elem_writefunc(fptr, END_TOKEN_BEGIN, data, END_TOKEN_BEGIN_LEN); - xml_elem_writefunc(fptr,el->name ? el->name : "None", data, 0); - xml_elem_writefunc(fptr, END_TOKEN_END, data, END_TOKEN_END_LEN); - } - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } -} - -/* print buf to file */ -static int file_out_fptr(void *f, const char *text, int size) -{ - fputs(text, (FILE *)f); - return 0; -} - -/* print buf to simplestring */ -static int simplestring_out_fptr(void *f, const char *text, int size) -{ - simplestring* buf = (simplestring*)f; - if(buf) { - simplestring_addn(buf, text, size); - } - return 0; -} - -/****f* xml_element/xml_elem_serialize_to_string - * NAME - * xml_elem_serialize_to_string - * SYNOPSIS - * void xml_element_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) - * FUNCTION - * writes element tree as XML into a newly allocated buffer - * INPUTS - * el - root element of tree - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * buf_len - length of returned buffer, if not null. - * RESULT - * char* or NULL. Must be free'd by caller. - * NOTES - * SEE ALSO - * xml_elem_serialize_to_stream () - * xml_elem_parse_buf () - * SOURCE - */ -char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) -{ - simplestring buf; - simplestring_init(&buf); - - xml_element_serialize(el, simplestring_out_fptr, (void *)&buf, options, 0); - - if(buf_len) { - *buf_len = buf.len; - } - - return buf.str; -} -/******/ - -/****f* xml_element/xml_elem_serialize_to_stream - * NAME - * xml_elem_serialize_to_stream - * SYNOPSIS - * void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) - * FUNCTION - * writes element tree as XML into a stream (typically an opened file) - * INPUTS - * el - root element of tree - * output - stream handle - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_parse_buf () - * SOURCE - */ -void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) -{ - xml_element_serialize(el, file_out_fptr, (void *)output, options, 0); -} -/******/ - -/*--------------------------* -* End xml_element Functions * -*--------------------------*/ - - -/*---------------------- -* Begin Expat Handlers * -*---------------------*/ - -typedef struct _xml_elem_data { - xml_element* root; - xml_element* current; - XML_ELEM_INPUT_OPTIONS input_options; - int needs_enc_conversion; -} xml_elem_data; - - -/* expat start of element handler */ -static void startElement(void *userData, const char *name, const char **attrs) -{ - xml_element *c; - xml_elem_data* mydata = (xml_elem_data*)userData; - const char** p = attrs; - - if(mydata) { - c = mydata->current; - - mydata->current = xml_elem_new(); - mydata->current->name = (char*)strdup(name); - mydata->current->parent = c; - - /* init attrs */ - while(p && *p) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); - if(attr) { - attr->key = strdup(*p); - attr->val = strdup(*(p+1)); - Q_PushTail(&mydata->current->attrs, attr); - - p += 2; - } - } - } -} - -/* expat end of element handler */ -static void endElement(void *userData, const char *name) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - - if(mydata && mydata->current && mydata->current->parent) { - Q_PushTail(&mydata->current->parent->children, mydata->current); - - mydata->current = mydata->current->parent; - } -} - -/* expat char data handler */ -static void charHandler(void *userData, - const char *s, - int len) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - if(mydata && mydata->current) { - - /* Check if we need to decode utf-8 parser output to another encoding */ - if(mydata->needs_enc_conversion && mydata->input_options->encoding) { - int new_len = 0; - char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding); - if(add_text) { - len = new_len; - simplestring_addn(&mydata->current->text, add_text, len); - free(add_text); - return; - } - } - simplestring_addn(&mydata->current->text, s, len); - } -} -/******/ - -/*-------------------* -* End Expat Handlers * -*-------------------*/ - -/*-------------------* -* xml_elem_parse_buf * -*-------------------*/ - -/****f* xml_element/xml_elem_parse_buf - * NAME - * xml_elem_parse_buf - * SYNOPSIS - * xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) - * FUNCTION - * parse a buffer containing XML into an xml_element in-memory tree - * INPUTS - * in_buf - buffer containing XML document - * len - length of buffer - * options - input options. optional - * error - error result data. optional. check if result is null. - * RESULT - * void - * NOTES - * The returned data must be free'd by caller - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_free () - * SOURCE - */ -xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) -{ - xml_element* xReturn = NULL; - char buf[100] = ""; - static STRUCT_XML_ELEM_INPUT_OPTIONS default_opts = {encoding_utf_8}; - - if(!options) { - options = &default_opts; - } - - if(in_buf) { - XML_Parser parser; - xml_elem_data mydata = {0}; - - parser = XML_ParserCreate(NULL); - - mydata.root = xml_elem_new(); - mydata.current = mydata.root; - mydata.input_options = options; - mydata.needs_enc_conversion = options->encoding && strcmp(options->encoding, encoding_utf_8); - - XML_SetElementHandler(parser, startElement, endElement); - XML_SetCharacterDataHandler(parser, charHandler); - - /* pass the xml_elem_data struct along */ - XML_SetUserData(parser, (void*)&mydata); - - if(!len) { - len = strlen(in_buf); - } - - /* parse the XML */ - if(XML_Parse(parser, in_buf, len, 1) == 0) { - enum XML_Error err_code = XML_GetErrorCode(parser); - int line_num = XML_GetCurrentLineNumber(parser); - int col_num = XML_GetCurrentColumnNumber(parser); - long byte_idx = XML_GetCurrentByteIndex(parser); - int byte_total = XML_GetCurrentByteCount(parser); - const char * error_str = XML_ErrorString(err_code); - if(byte_idx >= 0) { - snprintf(buf, - sizeof(buf), - "\n\tdata beginning %ld before byte index: %s\n", - byte_idx > 10 ? 10 : byte_idx, - in_buf + (byte_idx > 10 ? byte_idx - 10 : byte_idx)); - } - - fprintf(stderr, "expat reports error code %i\n" - "\tdescription: %s\n" - "\tline: %i\n" - "\tcolumn: %i\n" - "\tbyte index: %ld\n" - "\ttotal bytes: %i\n%s ", - err_code, error_str, line_num, - col_num, byte_idx, byte_total, buf); - - - /* error condition */ - if(error) { - error->parser_code = (long)err_code; - error->line = line_num; - error->column = col_num; - error->byte_index = byte_idx; - error->parser_error = error_str; - } - } - else { - xReturn = (xml_element*)Q_Head(&mydata.root->children); - xReturn->parent = NULL; - } - - XML_ParserFree(parser); - - - xml_elem_free_non_recurse(mydata.root); - } - - return xReturn; -} - -/******/ diff --git a/php/xmlrpc/libxmlrpc/xml_element.c.gcc4 b/php/xmlrpc/libxmlrpc/xml_element.c.gcc4 deleted file mode 100644 index 154f19b..0000000 --- a/php/xmlrpc/libxmlrpc/xml_element.c.gcc4 +++ /dev/null @@ -1,747 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - - - -/****h* ABOUT/xml_element - * NAME - * xml_element - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * CREATION DATE - * 06/2000 - * HISTORY - * $Log: xml_element.c,v $ - * Revision 1.6 2004/06/01 20:16:06 iliaa - * Fixed bug #28597 (xmlrpc_encode_request() incorrectly encodes chars in - * 200-210 range). - * Patch by: fernando dot nemec at folha dot com dot br - * - * Revision 1.5 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.4 2002/11/26 23:01:16 fmk - * removing unused variables - * - * Revision 1.3 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.9 2002/07/03 20:54:30 danda - * root element should not have a parent. patch from anon SF user - * - * Revision 1.8 2002/05/23 17:46:51 danda - * patch from mukund - fix non utf-8 encoding conversions - * - * Revision 1.7 2002/02/13 20:58:50 danda - * patch to make source more windows friendly, contributed by Jeff Lawson - * - * Revision 1.6 2002/01/08 01:06:55 danda - * enable format for parsers that are very picky. - * - * Revision 1.5 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 10/15/2000 -- danda -- adding robodoc documentation - * TODO - * Nicer external API. Get rid of macros. Make opaque types, etc. - * PORTABILITY - * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just - * about anything with minor mods. - * NOTES - * This code incorporates ideas from expat-ensor from http://xml.ensor.org. - * - * It was coded primarily to act as a go-between for expat and xmlrpc. To this - * end, it stores xml elements, their sub-elements, and their attributes in an - * in-memory tree. When expat is done parsing, the tree can be walked, thus - * retrieving the values. The code can also be used to build a tree via API then - * write out the tree to a buffer, thus "serializing" the xml. - * - * It turns out this is useful for other purposes, such as parsing config files. - * YMMV. - * - * Some Features: - * - output option for xml escaping data. Choices include no escaping, entity escaping, - * or CDATA sections. - * - output option for character encoding. Defaults to (none) utf-8. - * - output option for verbosity/readability. ultra-compact, newlines, pretty/level indented. - * - * BUGS - * there must be some. - ******/ - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include - -#include "xml_element.h" -#include "queue.h" -#include "expat.h" -#include "encodings.h" - -#define my_free(thing) if(thing) {free(thing); thing = 0;} - -#define XML_DECL_START "" -#define XML_DECL_END_LEN sizeof(XML_DECL_END) - 1 -#define START_TOKEN_BEGIN "<" -#define START_TOKEN_BEGIN_LEN sizeof(START_TOKEN_BEGIN) - 1 -#define START_TOKEN_END ">" -#define START_TOKEN_END_LEN sizeof(START_TOKEN_END) - 1 -#define EMPTY_START_TOKEN_END "/>" -#define EMPTY_START_TOKEN_END_LEN sizeof(EMPTY_START_TOKEN_END) - 1 -#define END_TOKEN_BEGIN "" -#define END_TOKEN_END_LEN sizeof(END_TOKEN_END) - 1 -#define ATTR_DELIMITER "\"" -#define ATTR_DELIMITER_LEN sizeof(ATTR_DELIMITER) - 1 -#define CDATA_BEGIN "" -#define CDATA_END_LEN sizeof(CDATA_END) - 1 -#define EQUALS "=" -#define EQUALS_LEN sizeof(EQUALS) - 1 -#define WHITESPACE " " -#define WHITESPACE_LEN sizeof(WHITESPACE) - 1 -#define NEWLINE "\n" -#define NEWLINE_LEN sizeof(NEWLINE) - 1 -#define MAX_VAL_BUF 144 -#define SCALAR_STR "SCALAR" -#define SCALAR_STR_LEN sizeof(SCALAR_STR) - 1 -#define VECTOR_STR "VECTOR" -#define VECTOR_STR_LEN sizeof(VECTOR_STR) - 1 -#define RESPONSE_STR "RESPONSE" -#define RESPONSE_STR_LEN sizeof(RESPONSE_STR) - 1 - - -/*----------------------------- -- Begin xml_element Functions - ------------------------------*/ - -/****f* xml_element/xml_elem_free_non_recurse - * NAME - * xml_elem_free_non_recurse - * SYNOPSIS - * void xml_elem_free_non_recurse(xml_element* root) - * FUNCTION - * free a single xml element. child elements will not be freed. - * INPUTS - * root - the element to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free_non_recurse(xml_element* root) { - if(root) { - xml_element_attr* attrs = Q_Head(&root->attrs); - while(attrs) { - my_free(attrs->key); - my_free(attrs->val); - my_free(attrs); - attrs = Q_Next(&root->attrs); - } - - Q_Destroy(&root->children); - Q_Destroy(&root->attrs); - my_free((char*)root->name); - simplestring_free(&root->text); - my_free(root); - } -} -/******/ - -/****f* xml_element/xml_elem_free - * NAME - * xml_elem_free - * SYNOPSIS - * void xml_elem_free(xml_element* root) - * FUNCTION - * free an xml element and all of its child elements - * INPUTS - * root - the root of an xml tree you would like to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free_non_recurse () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free(xml_element* root) { - if(root) { - xml_element* kids = Q_Head(&root->children); - while(kids) { - xml_elem_free(kids); - kids = Q_Next(&root->children); - } - xml_elem_free_non_recurse(root); - } -} -/******/ - -/****f* xml_element/xml_elem_new - * NAME - * xml_elem_new - * SYNOPSIS - * xml_element* xml_elem_new() - * FUNCTION - * allocates and initializes a new xml_element - * INPUTS - * none - * RESULT - * xml_element* or NULL. NULL indicates an out-of-memory condition. - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_free_non_recurse () - * SOURCE - */ -xml_element* xml_elem_new() { - xml_element* elem = calloc(1, sizeof(xml_element)); - if(elem) { - Q_Init(&elem->children); - Q_Init(&elem->attrs); - simplestring_init(&elem->text); - - /* init empty string in case we don't find any char data */ - simplestring_addn(&elem->text, "", 0); - } - return elem; -} -/******/ - -static int xml_elem_writefunc(int (*fptr)(void *data, const char *text, int size), const char *text, void *data, int len) -{ - return fptr && text ? fptr(data, text, len ? len : strlen(text)) : 0; -} - - - -static int create_xml_escape(char *pString, unsigned char c) -{ - int counter = 0; - - pString[counter++] = '&'; - pString[counter++] = '#'; - if(c >= 100) { - pString[counter++] = c / 100 + '0'; - c = c % 100; - } - pString[counter++] = c / 10 + '0'; - c = c % 10; - - pString[counter++] = c + '0'; - pString[counter++] = ';'; - return counter; -} - -#define non_ascii(c) (c > 127) -#define non_print(c) (!isprint(c)) -#define markup(c) (c == '&' || c == '\"' || c == '>' || c == '<') -#define entity_length(c) ( (c >= 100) ? 3 : ((c >= 10) ? 2 : 1) ) + 3; /* "&#" + c + ";" */ - -/* - * xml_elem_entity_escape - * - * Purpose: - * escape reserved xml chars and non utf-8 chars as xml entities - * Comments: - * The return value may be a new string, or null if no - * conversion was performed. In the latter case, *newlen will - * be 0. - * Flags (to escape) - * xml_elem_no_escaping = 0x000, - * xml_elem_entity_escaping = 0x002, // escape xml special chars as entities - * xml_elem_non_ascii_escaping = 0x008, // escape chars above 127 - * xml_elem_cdata_escaping = 0x010, // wrap in cdata - */ -static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, XML_ELEM_ESCAPING flags) { - char *pRetval = 0; - int iNewBufLen=0; - -#define should_escape(c, flag) ( ((flag & xml_elem_markup_escaping) && markup(c)) || \ - ((flag & xml_elem_non_ascii_escaping) && non_ascii(c)) || \ - ((flag & xml_elem_non_print_escaping) && non_print(c)) ) - - if(buf && *buf) { - const unsigned char *bufcopy; - char *NewBuffer; - int ToBeXmlEscaped=0; - int iLength; - bufcopy = buf; - iLength= old_len ? old_len : strlen(buf); - while(*bufcopy) { - if( should_escape(*bufcopy, flags) ) { - /* the length will increase by length of xml escape - the character length */ - iLength += entity_length(*bufcopy); - ToBeXmlEscaped=1; - } - bufcopy++; - } - - if(ToBeXmlEscaped) { - - NewBuffer= malloc(iLength+1); - if(NewBuffer) { - bufcopy=buf; - while(*bufcopy) { - if(should_escape(*bufcopy, flags)) { - iNewBufLen += create_xml_escape(NewBuffer+iNewBufLen,*bufcopy); - } - else { - NewBuffer[iNewBufLen++]=*bufcopy; - } - bufcopy++; - } - NewBuffer[iNewBufLen] = 0; - pRetval = NewBuffer; - } - } - } - - if(newlen) { - *newlen = iNewBufLen; - } - - return pRetval; -} - - -static void xml_element_serialize(xml_element *el, int (*fptr)(void *data, const char *text, int size), void *data, XML_ELEM_OUTPUT_OPTIONS options, int depth) -{ - int i; - static STRUCT_XML_ELEM_OUTPUT_OPTIONS default_opts = {xml_elem_pretty, xml_elem_markup_escaping | xml_elem_non_print_escaping, XML_DECL_ENCODING_DEFAULT}; - static char whitespace[] = " " - " " - " "; - depth++; - - if(!el) { - fprintf(stderr, "Nothing to write\n"); - return; - } - if(!options) { - options = &default_opts; - } - - /* print xml declaration if at root level */ - if(depth == 1) { - xml_elem_writefunc(fptr, XML_DECL_START, data, XML_DECL_START_LEN); - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_VERSION, data, XML_DECL_VERSION_LEN); - if(options->encoding && *options->encoding) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_ENCODING_ATTR, data, XML_DECL_ENCODING_ATTR_LEN); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, options->encoding, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - } - xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN); - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - /* begin element */ - xml_elem_writefunc(fptr,START_TOKEN_BEGIN, data, START_TOKEN_BEGIN_LEN); - if(el->name) { - xml_elem_writefunc(fptr, el->name, data, 0); - - /* write attrs, if any */ - if(Q_Size(&el->attrs)) { - xml_element_attr* iter = Q_Head(&el->attrs); - while( iter ) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, iter->key, data, 0); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, iter->val, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - - iter = Q_Next(&el->attrs); - } - } - } - else { - xml_elem_writefunc(fptr, "None", data, 0); - } - /* if no text and no children, use abbreviated form, eg: */ - if(!el->text.len && !Q_Size(&el->children)) { - xml_elem_writefunc(fptr, EMPTY_START_TOKEN_END, data, EMPTY_START_TOKEN_END_LEN); - } - /* otherwise, print element contents */ - else { - xml_elem_writefunc(fptr, START_TOKEN_END, data, START_TOKEN_END_LEN); - - /* print text, if any */ - if(el->text.len) { - char* escaped_str = el->text.str; - int buflen = el->text.len; - - if(options->escaping && options->escaping != xml_elem_cdata_escaping) { - escaped_str = xml_elem_entity_escape(el->text.str, buflen, &buflen, options->escaping ); - if(!escaped_str) { - escaped_str = el->text.str; - } - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_BEGIN, data, CDATA_BEGIN_LEN); - } - - xml_elem_writefunc(fptr, escaped_str, data, buflen); - - if(escaped_str != el->text.str) { - my_free(escaped_str); - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_END, data, CDATA_END_LEN); - } - } - /* no text, so print child elems */ - else { - xml_element *kids = Q_Head(&el->children); - i = 0; - while( kids ) { - if(i++ == 0) { - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - xml_element_serialize(kids, fptr, data, options, depth); - kids = Q_Next(&el->children); - } - if(i) { - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - } - } - - xml_elem_writefunc(fptr, END_TOKEN_BEGIN, data, END_TOKEN_BEGIN_LEN); - xml_elem_writefunc(fptr,el->name ? el->name : "None", data, 0); - xml_elem_writefunc(fptr, END_TOKEN_END, data, END_TOKEN_END_LEN); - } - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } -} - -/* print buf to file */ -static int file_out_fptr(void *f, const char *text, int size) -{ - fputs(text, (FILE *)f); - return 0; -} - -/* print buf to simplestring */ -static int simplestring_out_fptr(void *f, const char *text, int size) -{ - simplestring* buf = (simplestring*)f; - if(buf) { - simplestring_addn(buf, text, size); - } - return 0; -} - -/****f* xml_element/xml_elem_serialize_to_string - * NAME - * xml_elem_serialize_to_string - * SYNOPSIS - * void xml_element_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) - * FUNCTION - * writes element tree as XML into a newly allocated buffer - * INPUTS - * el - root element of tree - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * buf_len - length of returned buffer, if not null. - * RESULT - * char* or NULL. Must be free'd by caller. - * NOTES - * SEE ALSO - * xml_elem_serialize_to_stream () - * xml_elem_parse_buf () - * SOURCE - */ -char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) -{ - simplestring buf; - simplestring_init(&buf); - - xml_element_serialize(el, simplestring_out_fptr, (void *)&buf, options, 0); - - if(buf_len) { - *buf_len = buf.len; - } - - return buf.str; -} -/******/ - -/****f* xml_element/xml_elem_serialize_to_stream - * NAME - * xml_elem_serialize_to_stream - * SYNOPSIS - * void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) - * FUNCTION - * writes element tree as XML into a stream (typically an opened file) - * INPUTS - * el - root element of tree - * output - stream handle - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_parse_buf () - * SOURCE - */ -void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) -{ - xml_element_serialize(el, file_out_fptr, (void *)output, options, 0); -} -/******/ - -/*--------------------------* -* End xml_element Functions * -*--------------------------*/ - - -/*---------------------- -* Begin Expat Handlers * -*---------------------*/ - -typedef struct _xml_elem_data { - xml_element* root; - xml_element* current; - XML_ELEM_INPUT_OPTIONS input_options; - int needs_enc_conversion; -} xml_elem_data; - - -/* expat start of element handler */ -static void startElement(void *userData, const char *name, const char **attrs) -{ - xml_element *c; - xml_elem_data* mydata = (xml_elem_data*)userData; - const char** p = attrs; - - if(mydata) { - c = mydata->current; - - mydata->current = xml_elem_new(); - mydata->current->name = (char*)strdup(name); - mydata->current->parent = c; - - /* init attrs */ - while(p && *p) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); - if(attr) { - attr->key = strdup(*p); - attr->val = strdup(*(p+1)); - Q_PushTail(&mydata->current->attrs, attr); - - p += 2; - } - } - } -} - -/* expat end of element handler */ -static void endElement(void *userData, const char *name) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - - if(mydata && mydata->current && mydata->current->parent) { - Q_PushTail(&mydata->current->parent->children, mydata->current); - - mydata->current = mydata->current->parent; - } -} - -/* expat char data handler */ -static void charHandler(void *userData, - const char *s, - int len) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - if(mydata && mydata->current) { - - /* Check if we need to decode utf-8 parser output to another encoding */ - if(mydata->needs_enc_conversion && mydata->input_options->encoding) { - int new_len = 0; - char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding); - if(add_text) { - len = new_len; - simplestring_addn(&mydata->current->text, add_text, len); - free(add_text); - return; - } - } - simplestring_addn(&mydata->current->text, s, len); - } -} -/******/ - -/*-------------------* -* End Expat Handlers * -*-------------------*/ - -/*-------------------* -* xml_elem_parse_buf * -*-------------------*/ - -/****f* xml_element/xml_elem_parse_buf - * NAME - * xml_elem_parse_buf - * SYNOPSIS - * xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) - * FUNCTION - * parse a buffer containing XML into an xml_element in-memory tree - * INPUTS - * in_buf - buffer containing XML document - * len - length of buffer - * options - input options. optional - * error - error result data. optional. check if result is null. - * RESULT - * void - * NOTES - * The returned data must be free'd by caller - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_free () - * SOURCE - */ -xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) -{ - xml_element* xReturn = NULL; - char buf[100] = ""; - static STRUCT_XML_ELEM_INPUT_OPTIONS default_opts = {encoding_utf_8}; - - if(!options) { - options = &default_opts; - } - - if(in_buf) { - XML_Parser parser; - xml_elem_data mydata = {0}; - - parser = XML_ParserCreate(NULL); - - mydata.root = xml_elem_new(); - mydata.current = mydata.root; - mydata.input_options = options; - mydata.needs_enc_conversion = options->encoding && strcmp(options->encoding, encoding_utf_8); - - XML_SetElementHandler(parser, startElement, endElement); - XML_SetCharacterDataHandler(parser, charHandler); - - /* pass the xml_elem_data struct along */ - XML_SetUserData(parser, (void*)&mydata); - - if(!len) { - len = strlen(in_buf); - } - - /* parse the XML */ - if(XML_Parse(parser, in_buf, len, 1) == 0) { - enum XML_Error err_code = XML_GetErrorCode(parser); - int line_num = XML_GetCurrentLineNumber(parser); - int col_num = XML_GetCurrentColumnNumber(parser); - long byte_idx = XML_GetCurrentByteIndex(parser); - int byte_total = XML_GetCurrentByteCount(parser); - const char * error_str = XML_ErrorString(err_code); - if(byte_idx >= 0) { - snprintf(buf, - sizeof(buf), - "\n\tdata beginning %ld before byte index: %s\n", - byte_idx > 10 ? 10 : byte_idx, - in_buf + (byte_idx > 10 ? byte_idx - 10 : byte_idx)); - } - - fprintf(stderr, "expat reports error code %i\n" - "\tdescription: %s\n" - "\tline: %i\n" - "\tcolumn: %i\n" - "\tbyte index: %ld\n" - "\ttotal bytes: %i\n%s ", - err_code, error_str, line_num, - col_num, byte_idx, byte_total, buf); - - - /* error condition */ - if(error) { - error->parser_code = (long)err_code; - error->line = line_num; - error->column = col_num; - error->byte_index = byte_idx; - error->parser_error = error_str; - } - } - else { - xReturn = (xml_element*)Q_Head(&mydata.root->children); - xReturn->parent = NULL; - } - - XML_ParserFree(parser); - - - xml_elem_free_non_recurse(mydata.root); - } - - return xReturn; -} - -/******/ diff --git a/php/xmlrpc/libxmlrpc/xml_element.h b/php/xmlrpc/libxmlrpc/xml_element.h deleted file mode 100644 index cfe7ca2..0000000 --- a/php/xmlrpc/libxmlrpc/xml_element.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifndef __XML_ELEMENT_H__ - #define __XML_ELEMENT_H__ - -/* includes */ -#include -#include "queue.h" -#include "simplestring.h" -#include "encodings.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/****d* enum/XML_ELEM_VERBOSITY - * NAME - * XML_ELEM_VERBOSITY - * NOTES - * verbosity/readability options for generated xml - * SEE ALSO - * XML_ELEM_OUTPUT_OPTIONS - * SOURCE - */ -typedef enum _xml_elem_verbosity { - xml_elem_no_white_space, /* compact xml with no white space */ - xml_elem_newlines_only, /* add newlines for enhanced readability */ - xml_elem_pretty /* add newlines and indent accordint to depth */ -} XML_ELEM_VERBOSITY; -/******/ - - -/****d* enum/XML_ELEM_ESCAPING - * NAME - * XML_ELEM_ESCAPING - * NOTES - * xml escaping options for generated xml - * SEE ALSO - * XML_ELEM_OUTPUT_OPTIONS - * SOURCE - */ -typedef enum _xml_elem_escaping { - xml_elem_no_escaping = 0x000, - xml_elem_markup_escaping = 0x002, /* entity escape xml special chars */ - xml_elem_non_ascii_escaping = 0x008, /* entity escape chars above 127 */ - xml_elem_non_print_escaping = 0x010, /* entity escape non print (illegal) chars */ - xml_elem_cdata_escaping = 0x020, /* wrap in cdata section */ -} XML_ELEM_ESCAPING; -/******/ - - -/****s* struct/XML_ELEM_OUTPUT_OPTIONS - * NAME - * XML_ELEM_OUTPUT_OPTIONS - * NOTES - * defines various output options - * SOURCE - */ -typedef struct _xml_output_options { - XML_ELEM_VERBOSITY verbosity; /* length/verbosity of xml */ - XML_ELEM_ESCAPING escaping; /* how to escape special chars */ - const char* encoding; /* " ?> */ -} STRUCT_XML_ELEM_OUTPUT_OPTIONS, *XML_ELEM_OUTPUT_OPTIONS; -/******/ - -/****s* struct/XML_ELEM_INPUT_OPTIONS - * NAME - * XML_ELEM_INPUT_OPTIONS - * NOTES - * defines various input options - * SOURCE - */ -typedef struct _xml_input_options { - ENCODING_ID encoding; /* which encoding to use. */ -} STRUCT_XML_ELEM_INPUT_OPTIONS, *XML_ELEM_INPUT_OPTIONS; -/******/ - -/****s* struct/XML_ELEM_ERROR - * NAME - * XML_ELEM_ERROR - * NOTES - * defines an xml parser error - * SOURCE - */ -typedef struct _xml_elem_error { - int parser_code; - const char* parser_error; - long line; - long column; - long byte_index; -} STRUCT_XML_ELEM_ERROR, *XML_ELEM_ERROR; -/******/ - - -/*-************************ -* begin xml element stuff * -**************************/ - -/****s* struct/xml_elem_attr - * NAME - * xml_elem_attr - * NOTES - * representation of an xml attribute, foo="bar" - * SOURCE - */ -typedef struct _xml_element_attr { - char* key; /* attribute key */ - char* val; /* attribute value */ -} xml_element_attr; -/******/ - -/****s* struct/xml_elem_attr - * NAME - * xml_elem_attr - * NOTES - * representation of an xml element, eg - * SOURCE - */ -typedef struct _xml_element { - const char* name; /* element identifier */ - simplestring text; /* text contained between element begin/end pairs */ - struct _xml_element* parent; /* element's parent */ - - queue attrs; /* attribute list */ - queue children; /* child element list */ -} xml_element; -/******/ - -void xml_elem_free(xml_element* root); -void xml_elem_free_non_recurse(xml_element* root); -xml_element* xml_elem_new(void); -char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len); -void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options); -xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error); - -/*-********************** -* end xml element stuff * -************************/ - -/*-********************** -* Begin xml_element API * -************************/ - -/****d* VALUE/XMLRPC_MACROS - * NAME - * Some Helpful Macros - * NOTES - * Some macros for making life easier. Should be self-explanatory. - * SEE ALSO - * XMLRPC_AddValueToVector () - * XMLRPC_VectorGetValueWithID_Case () - * XMLRPC_VALUE - * SOURCE - */ -#define xml_elem_next_element(el) ((el) ? (xml_element *)Q_Next(&el->children) : NULL) -#define xml_elem_head_element(el) ((el) ? (xml_element *)Q_Head(&el->children) : NULL) -#define xml_elem_next_attr(el) ((el) ? (xml_element_attr *)Q_Next(&el->attrs) : NULL) -#define xml_elem_head_attr(el) ((el) ? (xml_element_attr *)Q_Head(&el->attrs) : NULL) -#define xml_elem_get_name(el) (char *)((el) ? el->name : NULL) -#define xml_elem_get_val(el) (char *)((el) ? el->text.str : NULL) -/******/ - - -/*-******************** -* End xml_element API * -**********************/ - -#ifdef __cplusplus -} -#endif - -#endif /* __XML_ELEMENT_H__ */ diff --git a/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c b/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c deleted file mode 100644 index b51d991..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_dandarpc.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include "xml_to_dandarpc.h" -#include "base64.h" - -/* list of tokens used in vocab */ -#define ELEM_METHODCALL "methodCall" -#define ELEM_METHODNAME "methodName" -#define ELEM_METHODRESPONSE "methodResponse" -#define ELEM_ROOT "simpleRPC" - -#define ATTR_ARRAY "array" -#define ATTR_BASE64 "base64" -#define ATTR_BOOLEAN "boolean" -#define ATTR_DATETIME "dateTime.iso8601" -#define ATTR_DOUBLE "double" -#define ATTR_ID "id" -#define ATTR_INT "int" -#define ATTR_MIXED "mixed" -#define ATTR_SCALAR "scalar" -#define ATTR_STRING "string" -#define ATTR_STRUCT "struct" -#define ATTR_TYPE "type" -#define ATTR_VECTOR "vector" -#define ATTR_VERSION "version" - -#define VAL_VERSION_0_9 "0.9" - - -XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xCurrent, xml_element* el) { - if(!xCurrent) { - xCurrent = XMLRPC_CreateValueEmpty(); - } - - if(el->name) { - const char* id = NULL; - const char* type = NULL; - xml_element_attr* attr_iter = Q_Head(&el->attrs); - - while(attr_iter) { - if(!strcmp(attr_iter->key, ATTR_ID)) { - id = attr_iter->val; - } - if(!strcmp(attr_iter->key, ATTR_TYPE)) { - type = attr_iter->val; - } - attr_iter = Q_Next(&el->attrs); - } - - if(id) { - XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact); - } - - if(!strcmp(el->name, ATTR_SCALAR)) { - if(!type || !strcmp(type, ATTR_STRING)) { - XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len); - } - else if(!strcmp(type, ATTR_INT)) { - XMLRPC_SetValueInt(xCurrent, atoi(el->text.str)); - } - else if(!strcmp(type, ATTR_BOOLEAN)) { - XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str)); - } - else if(!strcmp(type, ATTR_DOUBLE)) { - XMLRPC_SetValueDouble(xCurrent, atof(el->text.str)); - } - else if(!strcmp(type, ATTR_DATETIME)) { - XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str); - } - else if(!strcmp(type, ATTR_BASE64)) { - struct buffer_st buf; - base64_decode(&buf, el->text.str, el->text.len); - XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset); - buffer_delete(&buf); - } - } - else if(!strcmp(el->name, ATTR_VECTOR)) { - xml_element* iter = (xml_element*)Q_Head(&el->children); - - if(!type || !strcmp(type, ATTR_MIXED)) { - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed); - } - else if(!strcmp(type, ATTR_ARRAY)) { - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array); - } - else if(!strcmp(type, ATTR_STRUCT)) { - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct); - } - while( iter ) { - XMLRPC_VALUE xNext = XMLRPC_CreateValueEmpty(); - xml_element_to_DANDARPC_REQUEST_worker(request, xNext, iter); - XMLRPC_AddValueToVector(xCurrent, xNext); - iter = (xml_element*)Q_Next(&el->children); - } - } - else { - xml_element* iter = (xml_element*)Q_Head(&el->children); - while( iter ) { - xml_element_to_DANDARPC_REQUEST_worker(request, xCurrent, iter); - iter = (xml_element*)Q_Next(&el->children); - } - - if(!strcmp(el->name, ELEM_METHODCALL)) { - if(request) { - XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); - } - } - else if(!strcmp(el->name, ELEM_METHODRESPONSE)) { - if(request) { - XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); - } - } - else if(!strcmp(el->name, ELEM_METHODNAME)) { - if(request) { - XMLRPC_RequestSetMethodName(request, el->text.str); - } - } - } - } - return xCurrent; -} - -XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el) -{ - return xml_element_to_DANDARPC_REQUEST_worker(NULL, NULL, el); -} - -XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el) -{ - if(request) { - return XMLRPC_RequestSetData(request, xml_element_to_DANDARPC_REQUEST_worker(request, NULL, el)); - } - return NULL; -} - -xml_element* DANDARPC_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) { -#define BUF_SIZE 512 - xml_element* root = NULL; - if(node) { - char buf[BUF_SIZE]; - const char* id = XMLRPC_GetValueID(node); - XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); - XMLRPC_REQUEST_OUTPUT_OPTIONS output = XMLRPC_RequestGetOutputOptions(request); - int bNoAddType = (type == xmlrpc_string && request && output && output->xml_elem_opts.verbosity == xml_elem_no_white_space); - xml_element* elem_val = xml_elem_new(); - const char* pAttrType = NULL; - - xml_element_attr* attr_type = bNoAddType ? NULL : malloc(sizeof(xml_element_attr)); - - if(attr_type) { - attr_type->key = strdup(ATTR_TYPE); - attr_type->val = 0; - Q_PushTail(&elem_val->attrs, attr_type); - } - - elem_val->name = (type == xmlrpc_vector) ? strdup(ATTR_VECTOR) : strdup(ATTR_SCALAR); - - if(id && *id) { - xml_element_attr* attr_id = malloc(sizeof(xml_element_attr)); - if(attr_id) { - attr_id->key = strdup(ATTR_ID); - attr_id->val = strdup(id); - Q_PushTail(&elem_val->attrs, attr_id); - } - } - - switch(type) { - case xmlrpc_string: - pAttrType = ATTR_STRING; - simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); - break; - case xmlrpc_int: - pAttrType = ATTR_INT; - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_boolean: - pAttrType = ATTR_BOOLEAN; - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_double: - pAttrType = ATTR_DOUBLE; - snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_datetime: - pAttrType = ATTR_DATETIME; - simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); - break; - case xmlrpc_base64: - { - struct buffer_st buf; - pAttrType = ATTR_BASE64; - base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); - simplestring_addn(&elem_val->text, buf.data, buf.offset ); - buffer_delete(&buf); - } - break; - case xmlrpc_vector: - { - XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); - - switch(my_type) { - case xmlrpc_vector_array: - pAttrType = ATTR_ARRAY; - break; - case xmlrpc_vector_mixed: - pAttrType = ATTR_MIXED; - break; - case xmlrpc_vector_struct: - pAttrType = ATTR_STRUCT; - break; - default: - break; - } - - /* recurse through sub-elements */ - while( xIter ) { - xml_element* next_el = DANDARPC_to_xml_element_worker(request, xIter); - if(next_el) { - Q_PushTail(&elem_val->children, next_el); - } - xIter = XMLRPC_VectorNext(node); - } - } - break; - default: - break; - } - if(pAttrType && attr_type && !bNoAddType) { - attr_type->val = strdup(pAttrType); - } - root = elem_val; - } - return root; -} - -xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node) { - return DANDARPC_to_xml_element_worker(NULL, node); -} - -xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { - xml_element* wrapper = NULL; - xml_element* root = NULL; - if(request) { - XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); - const char* pStr = NULL; - xml_element_attr* version = malloc(sizeof(xml_element_attr)); - version->key = strdup(ATTR_VERSION); - version->val = strdup(VAL_VERSION_0_9); - - wrapper = xml_elem_new(); - - if(request_type == xmlrpc_request_response) { - pStr = ELEM_METHODRESPONSE; - } - else if(request_type == xmlrpc_request_call) { - pStr = ELEM_METHODCALL; - } - if(pStr) { - wrapper->name = strdup(pStr); - } - - root = xml_elem_new(); - root->name = strdup(ELEM_ROOT); - Q_PushTail(&root->attrs, version); - Q_PushTail(&root->children, wrapper); - - pStr = XMLRPC_RequestGetMethodName(request); - - if(pStr) { - xml_element* method = xml_elem_new(); - method->name = strdup(ELEM_METHODNAME); - simplestring_add(&method->text, pStr); - Q_PushTail(&wrapper->children, method); - } - Q_PushTail(&wrapper->children, - DANDARPC_to_xml_element_worker(request, XMLRPC_RequestGetData(request))); - } - return root; -} - diff --git a/php/xmlrpc/libxmlrpc/xml_to_dandarpc.h b/php/xmlrpc/libxmlrpc/xml_to_dandarpc.h deleted file mode 100644 index 6facb55..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_dandarpc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifndef XML_TO_DANDARPC_H - #define XML_TO_DANDARPC_H - -#include "time.h" -#include "xmlrpc.h" - -XMLRPC_VALUE xml_element_to_DANDARPC_VALUE(xml_element* el); -XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST(XMLRPC_REQUEST request, xml_element* el); -xml_element* DANDARPC_VALUE_to_xml_element(XMLRPC_VALUE node); -xml_element* DANDARPC_REQUEST_to_xml_element(XMLRPC_REQUEST request); - -#endif /* XML_TO_DANDARPC_H */ diff --git a/php/xmlrpc/libxmlrpc/xml_to_soap.c b/php/xmlrpc/libxmlrpc/xml_to_soap.c deleted file mode 100644 index 8390f06..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_soap.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) -*/ - - -/*-********************************************************************** -* TODO: * -* - [SOAP-ENC:position] read sparse arrays (and write?) * -* - [SOAP-ENC:offset] read partially transmitted arrays (and write?) * -* - read "flattened" multi-dimensional arrays. (don't bother writing) * -* * -* BUGS: * -* - does not read schema. thus only knows soap pre-defined types. * -* - references (probably) do not work. untested. * -* - does not expose SOAP-ENV:Header to application at all. * -* - does not use namespaces correctly, thus: * -* - namespaces are hard-coded in comparison tokens * -* - if a sender uses another namespace identifer, it will break * -************************************************************************/ - - -static const char rcsid[] = "#(@) $Id:"; - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include "xml_to_soap.h" -#include "base64.h" - -/* list of tokens used in vocab */ -#define TOKEN_ANY "xsd:ur-type" -#define TOKEN_ARRAY "SOAP-ENC:Array" -#define TOKEN_ARRAY_TYPE "SOAP-ENC:arrayType" -#define TOKEN_BASE64 "SOAP-ENC:base64" -#define TOKEN_BOOLEAN "xsd:boolean" -#define TOKEN_DATETIME "xsd:timeInstant" -#define TOKEN_DOUBLE "xsd:double" -#define TOKEN_FLOAT "xsd:float" -#define TOKEN_ID "id" -#define TOKEN_INT "xsd:int" -#define TOKEN_NULL "xsi:null" -#define TOKEN_STRING "xsd:string" -#define TOKEN_STRUCT "xsd:struct" -#define TOKEN_TYPE "xsi:type" -#define TOKEN_FAULT "SOAP-ENV:Fault" -#define TOKEN_MUSTUNDERSTAND "SOAP-ENV:mustUnderstand" -#define TOKEN_ACTOR "SOAP-ENV:actor" -#define TOKEN_ACTOR_NEXT "http://schemas.xmlsoap.org/soap/actor/next" - -#define TOKEN_XMLRPC_FAULTCODE "faultCode" -#define TOKEN_XMLRPC_FAULTSTRING "faultString" -#define TOKEN_SOAP_FAULTCODE "faultcode" -#define TOKEN_SOAP_FAULTSTRING "faultstring" -#define TOKEN_SOAP_FAULTDETAILS "details" -#define TOKEN_SOAP_FAULTACTOR "actor" - - -/* determine if a string represents a soap type, as used in element names */ -static inline int is_soap_type(const char* soap_type) { - return(strstr(soap_type, "SOAP-ENC:") || strstr(soap_type, "xsd:")) ? 1 : 0; -} - -/* utility func to generate a new attribute. possibly should be in xml_element.c?? */ -static xml_element_attr* new_attr(const char* key, const char* val) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); - if (attr) { - attr->key = key ? strdup(key) : NULL; - attr->val = val ? strdup(val) : NULL; - } - return attr; -} - -struct array_info { - char kids_type[30]; - unsigned long size; - /* ... ? */ -}; - - -/* parses soap arrayType attribute to generate an array_info structure. - * TODO: should deal with sparse, flattened, & multi-dimensional arrays - */ -static struct array_info* parse_array_type_info(const char* array_type) { - struct array_info* ai = NULL; - if (array_type) { - ai = (struct array_info*)calloc(1, sizeof(struct array_info)); - if (ai) { - char buf[128], *p; - snprintf(buf, sizeof(buf), "%s", array_type); - p = strchr(buf, '['); - if (p) { - *p = 0; - } - strcpy(ai->kids_type, buf); - } - } - return ai; -} - -/* performs heuristics on an xmlrpc_vector_array to determine - * appropriate soap arrayType string. - */ -static const char* get_array_soap_type(XMLRPC_VALUE node) { - XMLRPC_VALUE_TYPE_EASY type = xmlrpc_type_none; - - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); - int loopCount = 0; - const char* soapType = TOKEN_ANY; - - type = XMLRPC_GetValueTypeEasy(xIter); - xIter = XMLRPC_VectorNext(node); - - while (xIter) { - /* 50 seems like a decent # of loops. That will likely - * cover most cases. Any more and we start to sacrifice - * performance. - */ - if ( (XMLRPC_GetValueTypeEasy(xIter) != type) || loopCount >= 50) { - type = xmlrpc_type_none; - break; - } - loopCount ++; - - xIter = XMLRPC_VectorNext(node); - } - switch (type) { - case xmlrpc_type_none: - soapType = TOKEN_ANY; - break; - case xmlrpc_type_empty: - soapType = TOKEN_NULL; - break; - case xmlrpc_type_int: - soapType = TOKEN_INT; - break; - case xmlrpc_type_double: - soapType = TOKEN_DOUBLE; - break; - case xmlrpc_type_boolean: - soapType = TOKEN_BOOLEAN; - break; - case xmlrpc_type_string: - soapType = TOKEN_STRING; - break; - case xmlrpc_type_base64: - soapType = TOKEN_BASE64; - break; - case xmlrpc_type_datetime: - soapType = TOKEN_DATETIME; - break; - case xmlrpc_type_struct: - soapType = TOKEN_STRUCT; - break; - case xmlrpc_type_array: - soapType = TOKEN_ARRAY; - break; - case xmlrpc_type_mixed: - soapType = TOKEN_STRUCT; - break; - } - return soapType; -} - -/* determines wether a node is a fault or not, and of which type: - * 0 = not a fault, - * 1 = xmlrpc style fault - * 2 = soap style fault. - */ -static inline int get_fault_type(XMLRPC_VALUE node) { - if (XMLRPC_VectorGetValueWithID(node, TOKEN_XMLRPC_FAULTCODE) && - XMLRPC_VectorGetValueWithID(node, TOKEN_XMLRPC_FAULTSTRING)) { - return 1; - } - else if (XMLRPC_VectorGetValueWithID(node, TOKEN_SOAP_FAULTCODE) && - XMLRPC_VectorGetValueWithID(node, TOKEN_SOAP_FAULTSTRING)) { - return 2; - } - return 0; -} - -/* input: an XMLRPC_VALUE representing a fault struct in xml-rpc style. - * output: an XMLRPC_VALUE representing a fault struct in soap style, - * with xmlrpc codes mapped to soap codes, and all other values preserved. - * note that the returned value is a completely new value, and must be freed. - * the input value is untouched. - */ -static XMLRPC_VALUE gen_fault_xmlrpc(XMLRPC_VALUE node, xml_element* el_target) { - XMLRPC_VALUE xDup = XMLRPC_DupValueNew(node); - XMLRPC_VALUE xCode = XMLRPC_VectorGetValueWithID(xDup, TOKEN_XMLRPC_FAULTCODE); - XMLRPC_VALUE xStr = XMLRPC_VectorGetValueWithID(xDup, TOKEN_XMLRPC_FAULTSTRING); - - XMLRPC_SetValueID(xCode, TOKEN_SOAP_FAULTCODE, 0); - XMLRPC_SetValueID(xStr, TOKEN_SOAP_FAULTSTRING, 0); - - /* rough mapping of xmlrpc fault codes to soap codes */ - switch (XMLRPC_GetValueInt(xCode)) { - case -32700: /* "parse error. not well formed", */ - case -32701: /* "parse error. unsupported encoding" */ - case -32702: /* "parse error. invalid character for encoding" */ - case -32600: /* "server error. invalid xml-rpc. not conforming to spec." */ - case -32601: /* "server error. requested method not found" */ - case -32602: /* "server error. invalid method parameters" */ - XMLRPC_SetValueString(xCode, "SOAP-ENV:Client", 0); - break; - case -32603: /* "server error. internal xml-rpc error" */ - case -32500: /* "application error" */ - case -32400: /* "system error" */ - case -32300: /* "transport error */ - XMLRPC_SetValueString(xCode, "SOAP-ENV:Server", 0); - break; - } - return xDup; -} - -/* returns a new XMLRPC_VALUE representing a soap fault, comprised of a struct with four keys. */ -static XMLRPC_VALUE gen_soap_fault(const char* fault_code, const char* fault_string, - const char* actor, const char* details) { - XMLRPC_VALUE xReturn = XMLRPC_CreateVector(TOKEN_FAULT, xmlrpc_vector_struct); - XMLRPC_AddValuesToVector(xReturn, - XMLRPC_CreateValueString(TOKEN_SOAP_FAULTCODE, fault_code, 0), - XMLRPC_CreateValueString(TOKEN_SOAP_FAULTSTRING, fault_string, 0), - XMLRPC_CreateValueString(TOKEN_SOAP_FAULTACTOR, actor, 0), - XMLRPC_CreateValueString(TOKEN_SOAP_FAULTDETAILS, details, 0), - NULL); - return xReturn; -} - -/* translates xml soap dom to native data structures. recursive. */ -XMLRPC_VALUE xml_element_to_SOAP_REQUEST_worker(XMLRPC_REQUEST request, - XMLRPC_VALUE xParent, - struct array_info* parent_array, - XMLRPC_VALUE xCurrent, - xml_element* el, - int depth) { - XMLRPC_REQUEST_TYPE rtype = xmlrpc_request_none; - - /* no current element on first call */ - if (!xCurrent) { - xCurrent = XMLRPC_CreateValueEmpty(); - } - - /* increment recursion depth guage */ - depth ++; - - /* safety first. must have a valid element */ - if (el && el->name) { - const char* id = NULL; - const char* type = NULL, *arrayType=NULL, *actor = NULL; - xml_element_attr* attr_iter = Q_Head(&el->attrs); - int b_must_understand = 0; - - /* in soap, types may be specified in either element name -or- with xsi:type attribute. */ - if (is_soap_type(el->name)) { - type = el->name; - } - /* if our parent node, by definition a vector, is not an array, then - our element name must be our key identifier. */ - else if (XMLRPC_GetVectorType(xParent) != xmlrpc_vector_array) { - id = el->name; - if(!strcmp(id, "item")) { - } - } - - /* iterate through element attributes, pick out useful stuff. */ - while (attr_iter) { - /* element's type */ - if (!strcmp(attr_iter->key, TOKEN_TYPE)) { - type = attr_iter->val; - } - /* array type */ - else if (!strcmp(attr_iter->key, TOKEN_ARRAY_TYPE)) { - arrayType = attr_iter->val; - } - /* must understand, sometimes present in headers. */ - else if (!strcmp(attr_iter->key, TOKEN_MUSTUNDERSTAND)) { - b_must_understand = strchr(attr_iter->val, '1') ? 1 : 0; - } - /* actor, used in conjuction with must understand. */ - else if (!strcmp(attr_iter->key, TOKEN_ACTOR)) { - actor = attr_iter->val; - } - attr_iter = Q_Next(&el->attrs); - } - - /* check if caller says we must understand something in a header. */ - if (b_must_understand) { - /* is must understand actually indended for us? - BUG: spec says we should also determine if actor is our URL, but - we do not have that information. */ - if (!actor || !strcmp(actor, TOKEN_ACTOR_NEXT)) { - /* TODO: implement callbacks or other mechanism for applications - to "understand" these headers. For now, we just bail if we - get a mustUnderstand header intended for us. */ - XMLRPC_RequestSetError(request, - gen_soap_fault("SOAP-ENV:MustUnderstand", - "SOAP Must Understand Error", - "", "")); - return xCurrent; - } - } - - /* set id (key) if one was found. */ - if (id) { - XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact); - } - - /* according to soap spec, - depth 1 = Envelope, 2 = Header, Body & Fault, 3 = methodcall or response. */ - if (depth == 3) { - const char* methodname = el->name; - char* p = NULL; - - /* BUG: we determine request or response type using presence of "Response" in element name. - According to spec, this is only recommended, not required. Apparently, implementations - are supposed to know the type of action based on state, which strikes me as a bit lame. - Anyway, we don't have that state info, thus we use Response as a heuristic. */ - rtype = -#ifdef strcasestr - strcasestr(el->name, "response") ? xmlrpc_request_response : xmlrpc_request_call; -#else - strstr(el->name, "esponse") ? xmlrpc_request_response : xmlrpc_request_call; -#endif - XMLRPC_RequestSetRequestType(request, rtype); - - /* Get methodname. strip xml namespace crap. */ - p = strchr(el->name, ':'); - if (p) { - methodname = p + 1; - } - if (rtype == xmlrpc_request_call) { - XMLRPC_RequestSetMethodName(request, methodname); - } - } - - - /* Next, we begin to convert actual values. if no children, then must be a scalar value. */ - if (!Q_Size(&el->children)) { - if (!type && parent_array && parent_array->kids_type[0]) { - type = parent_array->kids_type; - } - if (!type || !strcmp(type, TOKEN_STRING)) { - XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len); - } - else if (!strcmp(type, TOKEN_INT)) { - XMLRPC_SetValueInt(xCurrent, atoi(el->text.str)); - } - else if (!strcmp(type, TOKEN_BOOLEAN)) { - XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str)); - } - else if (!strcmp(type, TOKEN_DOUBLE) || - !strcmp(type, TOKEN_FLOAT)) { - XMLRPC_SetValueDouble(xCurrent, atof(el->text.str)); - } - else if (!strcmp(type, TOKEN_NULL)) { - /* already an empty val. do nothing. */ - } - else if (!strcmp(type, TOKEN_DATETIME)) { - XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str); - } - else if (!strcmp(type, TOKEN_BASE64)) { - struct buffer_st buf; - base64_decode(&buf, el->text.str, el->text.len); - XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset); - buffer_delete(&buf); - } - } - /* Element has children, thus a vector, or "compound type" in soap-speak. */ - else { - struct array_info* ai = NULL; - xml_element* iter = (xml_element*)Q_Head(&el->children); - - if (!type || !strcmp(type, TOKEN_STRUCT)) { - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct); - } - else if (!strcmp(type, TOKEN_ARRAY) || arrayType != NULL) { - /* determine magic associated with soap array type. - this is passed down as we recurse, so our children have access to the info. */ - ai = parse_array_type_info(arrayType); // alloc'ed ai free'd below. - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array); - } - else { - /* mixed is probably closest thing we have to compound type. */ - XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed); - } - /* Recurse, adding values as we go. Check for error during recursion - and if found, bail. this short-circuits us out of the recursion. */ - while ( iter && !XMLRPC_RequestGetError(request) ) { - XMLRPC_VALUE xNext = NULL; - /* top level elements don't actually represent values, so we just pass the - current value along until we are deep enough. */ - if ( depth <= 2 || - (rtype == xmlrpc_request_response && depth <= 3) ) { - xml_element_to_SOAP_REQUEST_worker(request, NULL, ai, xCurrent, iter, depth); - } - /* ready to do some actual de-serialization. create a new empty value and - pass that along to be init'd, then add it to our current vector. */ - else { - xNext = XMLRPC_CreateValueEmpty(); - xml_element_to_SOAP_REQUEST_worker(request, xCurrent, ai, xNext, iter, depth); - XMLRPC_AddValueToVector(xCurrent, xNext); - } - iter = (xml_element*)Q_Next(&el->children); - } - /* cleanup */ - if (ai) { - free(ai); - } - } - } - return xCurrent; -} - -/* Convert soap xml dom to XMLRPC_VALUE, sans request info. untested. */ -XMLRPC_VALUE xml_element_to_SOAP_VALUE(xml_element* el) -{ - return xml_element_to_SOAP_REQUEST_worker(NULL, NULL, NULL, NULL, el, 0); -} - -/* Convert soap xml dom to XMLRPC_REQUEST */ -XMLRPC_VALUE xml_element_to_SOAP_REQUEST(XMLRPC_REQUEST request, xml_element* el) -{ - if (request) { - return XMLRPC_RequestSetData(request, xml_element_to_SOAP_REQUEST_worker(request, NULL, NULL, NULL, el, 0)); - } - return NULL; -} - - -/* translates data structures to soap/xml. recursive */ -xml_element* SOAP_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) { -#define BUF_SIZE 128 - xml_element* elem_val = NULL; - if (node) { - int bFreeNode = 0; /* sometimes we may need to free 'node' variable */ - char buf[BUF_SIZE]; - XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(node); - char* pName = NULL, *pAttrType = NULL; - - /* create our return value element */ - elem_val = xml_elem_new(); - - switch (type) { - case xmlrpc_type_struct: - case xmlrpc_type_mixed: - case xmlrpc_type_array: - if (type == xmlrpc_type_array) { - /* array's are _very_ special in soap. - TODO: Should handle sparse/partial arrays here. */ - - /* determine soap array type. */ - const char* type = get_array_soap_type(node); - xml_element_attr* attr_array_type = NULL; - - /* specify array kids type and array size. */ - snprintf(buf, sizeof(buf), "%s[%i]", type, XMLRPC_VectorSize(node)); - attr_array_type = new_attr(TOKEN_ARRAY_TYPE, buf); - - Q_PushTail(&elem_val->attrs, attr_array_type); - - pAttrType = TOKEN_ARRAY; - } - /* check for fault, which is a rather special case. - (can't these people design anything consistent/simple/elegant?) */ - else if (type == xmlrpc_type_struct) { - int fault_type = get_fault_type(node); - if (fault_type) { - if (fault_type == 1) { - /* gen fault from xmlrpc style fault codes - notice that we get a new node, which must be freed herein. */ - node = gen_fault_xmlrpc(node, elem_val); - bFreeNode = 1; - } - pName = TOKEN_FAULT; - } - } - - { - /* recurse through sub-elements */ - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); - while ( xIter ) { - xml_element* next_el = SOAP_to_xml_element_worker(request, xIter); - if (next_el) { - Q_PushTail(&elem_val->children, next_el); - } - xIter = XMLRPC_VectorNext(node); - } - } - - break; - - /* handle scalar types */ - case xmlrpc_type_empty: - pAttrType = TOKEN_NULL; - break; - case xmlrpc_type_string: - pAttrType = TOKEN_STRING; - simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); - break; - case xmlrpc_type_int: - pAttrType = TOKEN_INT; - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_type_boolean: - pAttrType = TOKEN_BOOLEAN; - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_type_double: - pAttrType = TOKEN_DOUBLE; - snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_type_datetime: - { - time_t tt = XMLRPC_GetValueDateTime(node); - struct tm *tm = localtime (&tt); - pAttrType = TOKEN_DATETIME; - if(strftime (buf, BUF_SIZE, "%Y-%m-%dT%H:%M:%SZ", tm)) { - simplestring_add(&elem_val->text, buf); - } - } - break; - case xmlrpc_type_base64: - { - struct buffer_st buf; - pAttrType = TOKEN_BASE64; - base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); - simplestring_addn(&elem_val->text, buf.data, buf.offset ); - buffer_delete(&buf); - } - break; - break; - default: - break; - } - - /* determining element's name is a bit tricky, due to soap semantics. */ - if (!pName) { - /* if the value's type is known... */ - if (pAttrType) { - /* see if it has an id (key). If so, use that as name, and type as an attribute. */ - pName = (char*)XMLRPC_GetValueID(node); - if (pName) { - Q_PushTail(&elem_val->attrs, new_attr(TOKEN_TYPE, pAttrType)); - } - - /* otherwise, use the type as the name. */ - else { - pName = pAttrType; - } - } - /* if the value's type is not known... (a rare case?) */ - else { - /* see if it has an id (key). otherwise, default to generic "item" */ - pName = (char*)XMLRPC_GetValueID(node); - if (!pName) { - pName = "item"; - } - } - } - elem_val->name = strdup(pName); - - /* cleanup */ - if (bFreeNode) { - XMLRPC_CleanupValue(node); - } - } - return elem_val; -} - -/* convert XMLRPC_VALUE to soap xml dom. untested. */ -xml_element* SOAP_VALUE_to_xml_element(XMLRPC_VALUE node) { - return SOAP_to_xml_element_worker(NULL, node); -} - -/* convert XMLRPC_REQUEST to soap xml dom. */ -xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) { - xml_element* root = xml_elem_new(); - - /* safety first. */ - if (root) { - xml_element* body = xml_elem_new(); - root->name = strdup("SOAP-ENV:Envelope"); - - /* silly namespace stuff */ - Q_PushTail(&root->attrs, new_attr("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/")); - Q_PushTail(&root->attrs, new_attr("xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance")); - Q_PushTail(&root->attrs, new_attr("xmlns:xsd", "http://www.w3.org/1999/XMLSchema")); - Q_PushTail(&root->attrs, new_attr("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/")); - Q_PushTail(&root->attrs, new_attr("xmlns:si", "http://soapinterop.org/xsd")); - Q_PushTail(&root->attrs, new_attr("xmlns:ns6", "http://testuri.org")); - Q_PushTail(&root->attrs, new_attr("SOAP-ENV:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/")); - - /* Q_PushHead(&root->attrs, new_attr("xmlns:ks", "http://kitchen.sink.org/soap/everything/under/sun")); - JUST KIDDING!! :-) ----> ------------------------------------------------- */ - - if (body) { - /* go ahead and serialize first... */ - xml_element* el_serialized = - SOAP_to_xml_element_worker(request, - XMLRPC_RequestGetData(request)); - - /* check for fault, in which case, there is no intermediate element */ - if (el_serialized && !strcmp(el_serialized->name, TOKEN_FAULT)) { - Q_PushTail(&body->children, el_serialized); - } - /* usual case: not a fault. Add Response element in between. */ - else { - xml_element* rpc = xml_elem_new(); - - if (rpc) { - const char* methodname = XMLRPC_RequestGetMethodName(request); - XMLRPC_REQUEST_TYPE rtype = XMLRPC_RequestGetRequestType(request); - - /* if we are making a request, we want to use the methodname as is. */ - if (rtype == xmlrpc_request_call) { - if (methodname) { - rpc->name = strdup(methodname); - } - } - /* if it's a response, we append "Response". Also, given xmlrpc-epi - API/architecture, it's likely that we don't have a methodname for - the response, so we have to check that. */ - else { - char buf[128]; - snprintf(buf, sizeof(buf), "%s%s", - methodname ? methodname : "", - "Response"); - - rpc->name = strdup(buf); - } - - /* add serialized data to method call/response. - add method call/response to body element */ - if (rpc->name) { - if(el_serialized) { - if(Q_Size(&el_serialized->children) && rtype == xmlrpc_request_call) { - xml_element* iter = (xml_element*)Q_Head(&el_serialized->children); - while(iter) { - Q_PushTail(&rpc->children, iter); - iter = (xml_element*)Q_Next(&el_serialized->children); - } - xml_elem_free_non_recurse(el_serialized); - } - else { - Q_PushTail(&rpc->children, el_serialized); - } - } - - Q_PushTail(&body->children, rpc); - } - else { - /* no method name?! - TODO: fault here...? */ - } - } - } - body->name = strdup("SOAP-ENV:Body"); - Q_PushTail(&root->children, body); - } - } - - return root; -} - diff --git a/php/xmlrpc/libxmlrpc/xml_to_soap.h b/php/xmlrpc/libxmlrpc/xml_to_soap.h deleted file mode 100644 index 9ae9308..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_soap.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -#ifndef XML_TO_SOAP_H - #define XML_TO_SOAP_H - -#include "xmlrpc.h" - -XMLRPC_VALUE xml_element_to_SOAP_VALUE(xml_element* el); -XMLRPC_VALUE xml_element_to_SOAP_REQUEST(XMLRPC_REQUEST request, xml_element* el); -xml_element* SOAP_VALUE_to_xml_element(XMLRPC_VALUE node); -xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request); - -#endif /* XML_TO_XMLRPC_H */ diff --git a/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.c b/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.c deleted file mode 100644 index c76b00f..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include "xml_to_xmlrpc.h" -#include "base64.h" - -/* list of tokens used in vocab */ -#define ELEM_ARRAY "array" -#define ELEM_BASE64 "base64" -#define ELEM_BOOLEAN "boolean" -#define ELEM_DATA "data" -#define ELEM_DATETIME "dateTime.iso8601" -#define ELEM_DOUBLE "double" -#define ELEM_FAULT "fault" -#define ELEM_FAULTCODE "faultCode" -#define ELEM_FAULTSTRING "faultString" -#define ELEM_I4 "i4" -#define ELEM_INT "int" -#define ELEM_MEMBER "member" -#define ELEM_METHODCALL "methodCall" -#define ELEM_METHODNAME "methodName" -#define ELEM_METHODRESPONSE "methodResponse" -#define ELEM_NAME "name" -#define ELEM_NIL "nil" -#define ELEM_PARAM "param" -#define ELEM_PARAMS "params" -#define ELEM_STRING "string" -#define ELEM_STRUCT "struct" -#define ELEM_VALUE "value" - - -XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE parent_vector, XMLRPC_VALUE current_val, xml_element* el) { - if (!current_val) { - /* This should only be the case for the first element */ - current_val = XMLRPC_CreateValueEmpty(); - } - - if (el->name) { - - /* first, deal with the crazy/stupid fault format */ - if (!strcmp(el->name, ELEM_FAULT)) { - xml_element* fault_value = (xml_element*)Q_Head(&el->children); - XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); - - if(fault_value) { - xml_element* fault_struct = (xml_element*)Q_Head(&fault_value->children); - if(fault_struct) { - xml_element* iter = (xml_element*)Q_Head(&fault_struct->children); - - while (iter) { - XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); - xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); - XMLRPC_AddValueToVector(current_val, xNextVal); - iter = (xml_element*)Q_Next(&fault_struct->children); - } - } - } - } - else if (!strcmp(el->name, ELEM_DATA) /* should be ELEM_ARRAY, but there is an extra level. weird */ - || (!strcmp(el->name, ELEM_PARAMS) && - (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call)) ) { /* this "PARAMS" concept is silly. dave?! */ - xml_element* iter = (xml_element*)Q_Head(&el->children); - XMLRPC_SetIsVector(current_val, xmlrpc_vector_array); - - while (iter) { - XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); - xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); - XMLRPC_AddValueToVector(current_val, xNextVal); - iter = (xml_element*)Q_Next(&el->children); - } - } - else if (!strcmp(el->name, ELEM_STRUCT)) { - xml_element* iter = (xml_element*)Q_Head(&el->children); - XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); - - while ( iter ) { - XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); - xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); - XMLRPC_AddValueToVector(current_val, xNextVal); - iter = (xml_element*)Q_Next(&el->children); - } - } - else if (!strcmp(el->name, ELEM_STRING) || - (!strcmp(el->name, ELEM_VALUE) && Q_Size(&el->children) == 0)) { - XMLRPC_SetValueString(current_val, el->text.str, el->text.len); - } - else if (!strcmp(el->name, ELEM_NAME)) { - XMLRPC_SetValueID_Case(current_val, el->text.str, 0, xmlrpc_case_exact); - } - else if (!strcmp(el->name, ELEM_INT) || !strcmp(el->name, ELEM_I4)) { - XMLRPC_SetValueInt(current_val, atoi(el->text.str)); - } - else if (!strcmp(el->name, ELEM_BOOLEAN)) { - XMLRPC_SetValueBoolean(current_val, atoi(el->text.str)); - } - else if (!strcmp(el->name, ELEM_DOUBLE)) { - XMLRPC_SetValueDouble(current_val, atof(el->text.str)); - } - else if (!strcmp(el->name, ELEM_DATETIME)) { - XMLRPC_SetValueDateTime_ISO8601(current_val, el->text.str); - } - else if (!strcmp(el->name, ELEM_BASE64)) { - struct buffer_st buf; - base64_decode(&buf, el->text.str, el->text.len); - XMLRPC_SetValueBase64(current_val, buf.data, buf.offset); - buffer_delete(&buf); - } - else { - xml_element* iter; - - if (!strcmp(el->name, ELEM_METHODCALL)) { - if (request) { - XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); - } - } - else if (!strcmp(el->name, ELEM_METHODRESPONSE)) { - if (request) { - XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); - } - } - else if (!strcmp(el->name, ELEM_METHODNAME)) { - if (request) { - XMLRPC_RequestSetMethodName(request, el->text.str); - } - } - - iter = (xml_element*)Q_Head(&el->children); - while ( iter ) { - xml_element_to_XMLRPC_REQUEST_worker(request, parent_vector, - current_val, iter); - iter = (xml_element*)Q_Next(&el->children); - } - } - } - return current_val; -} - -XMLRPC_VALUE xml_element_to_XMLRPC_VALUE(xml_element* el) -{ - return xml_element_to_XMLRPC_REQUEST_worker(NULL, NULL, NULL, el); -} - -XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST(XMLRPC_REQUEST request, xml_element* el) -{ - if (request) { - return XMLRPC_RequestSetData(request, xml_element_to_XMLRPC_REQUEST_worker(request, NULL, NULL, el)); - } - return NULL; -} - -xml_element* XMLRPC_to_xml_element_worker(XMLRPC_VALUE current_vector, XMLRPC_VALUE node, - XMLRPC_REQUEST_TYPE request_type, int depth) { -#define BUF_SIZE 512 - xml_element* root = NULL; - if (node) { - char buf[BUF_SIZE]; - XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(node); - XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(node); - xml_element* elem_val = xml_elem_new(); - - /* special case for when root element is not an array */ - if (depth == 0 && - !(type == xmlrpc_vector && - vtype == xmlrpc_vector_array && - request_type == xmlrpc_request_call) ) { - int bIsFault = (vtype == xmlrpc_vector_struct && XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)); - - xml_element* next_el = XMLRPC_to_xml_element_worker(NULL, node, request_type, depth + 1); - if (next_el) { - Q_PushTail(&elem_val->children, next_el); - } - elem_val->name = strdup(bIsFault ? ELEM_FAULT : ELEM_PARAMS); - } - else { - switch (type) { - case xmlrpc_empty: /* treat null value as empty string in xmlrpc. */ - case xmlrpc_nil: - elem_val->name = strdup(ELEM_NIL); - break; - case xmlrpc_string: - elem_val->name = strdup(ELEM_STRING); - simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node)); - break; - case xmlrpc_int: - elem_val->name = strdup(ELEM_INT); - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_boolean: - elem_val->name = strdup(ELEM_BOOLEAN); - snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_double: - elem_val->name = strdup(ELEM_DOUBLE); - snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node)); - simplestring_add(&elem_val->text, buf); - break; - case xmlrpc_datetime: - elem_val->name = strdup(ELEM_DATETIME); - simplestring_add(&elem_val->text, XMLRPC_GetValueDateTime_ISO8601(node)); - break; - case xmlrpc_base64: - { - struct buffer_st buf; - elem_val->name = strdup(ELEM_BASE64); - base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node)); - simplestring_addn(&elem_val->text, buf.data, buf.offset ); - buffer_delete(&buf); - } - break; - case xmlrpc_vector: - { - XMLRPC_VECTOR_TYPE my_type = XMLRPC_GetVectorType(node); - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node); - xml_element* root_vector_elem = elem_val; - - switch (my_type) { - case xmlrpc_vector_array: - { - if(depth == 0) { - elem_val->name = strdup(ELEM_PARAMS); - } - else { - /* Hi my name is Dave and I like to make things as confusing - * as possible, thus I will throw in this 'data' element - * where it absolutely does not belong just so that people - * cannot code arrays and structs in a similar and straight - * forward manner. Have a good day. - * - * GRRRRRRRRR! - */ - xml_element* data = xml_elem_new(); - data->name = strdup(ELEM_DATA); - - elem_val->name = strdup(ELEM_ARRAY); - Q_PushTail(&elem_val->children, data); - root_vector_elem = data; - } - } - break; - case xmlrpc_vector_mixed: /* not officially supported */ - case xmlrpc_vector_struct: - elem_val->name = strdup(ELEM_STRUCT); - break; - default: - break; - } - - /* recurse through sub-elements */ - while ( xIter ) { - xml_element* next_el = XMLRPC_to_xml_element_worker(node, xIter, request_type, depth + 1); - if (next_el) { - Q_PushTail(&root_vector_elem->children, next_el); - } - xIter = XMLRPC_VectorNext(node); - } - } - break; - default: - break; - } - } - - { - XMLRPC_VECTOR_TYPE vtype = XMLRPC_GetVectorType(current_vector); - - if (depth == 1) { - xml_element* value = xml_elem_new(); - value->name = strdup(ELEM_VALUE); - - /* yet another hack for the "fault" crap */ - if (XMLRPC_VectorGetValueWithID(node, ELEM_FAULTCODE)) { - root = value; - } - else { - xml_element* param = xml_elem_new(); - param->name = strdup(ELEM_PARAM); - - Q_PushTail(¶m->children, value); - - root = param; - } - Q_PushTail(&value->children, elem_val); - } - else if (vtype == xmlrpc_vector_struct || vtype == xmlrpc_vector_mixed) { - xml_element* member = xml_elem_new(); - xml_element* name = xml_elem_new(); - xml_element* value = xml_elem_new(); - - member->name = strdup(ELEM_MEMBER); - name->name = strdup(ELEM_NAME); - value->name = strdup(ELEM_VALUE); - - simplestring_add(&name->text, XMLRPC_GetValueID(node)); - - Q_PushTail(&member->children, name); - Q_PushTail(&member->children, value); - Q_PushTail(&value->children, elem_val); - - root = member; - } - else if (vtype == xmlrpc_vector_array) { - xml_element* value = xml_elem_new(); - - value->name = strdup(ELEM_VALUE); - - Q_PushTail(&value->children, elem_val); - - root = value; - } - else if (vtype == xmlrpc_vector_none) { - /* no parent. non-op */ - root = elem_val; - } - else { - xml_element* value = xml_elem_new(); - - value->name = strdup(ELEM_VALUE); - - Q_PushTail(&value->children, elem_val); - - root = value; - } - } - } - return root; -} - -xml_element* XMLRPC_VALUE_to_xml_element(XMLRPC_VALUE node) { - return XMLRPC_to_xml_element_worker(NULL, node, xmlrpc_request_none, 0); -} - -xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request) { - xml_element* wrapper = NULL; - if (request) { - const char* pStr = NULL; - XMLRPC_REQUEST_TYPE request_type = XMLRPC_RequestGetRequestType(request); - XMLRPC_VALUE xParams = XMLRPC_RequestGetData(request); - - wrapper = xml_elem_new(); - - if (request_type == xmlrpc_request_call) { - pStr = ELEM_METHODCALL; - } - else if (request_type == xmlrpc_request_response) { - pStr = ELEM_METHODRESPONSE; - } - if (pStr) { - wrapper->name = strdup(pStr); - } - - if(request_type == xmlrpc_request_call) { - pStr = XMLRPC_RequestGetMethodName(request); - - if (pStr) { - xml_element* method = xml_elem_new(); - method->name = strdup(ELEM_METHODNAME); - simplestring_add(&method->text, pStr); - Q_PushTail(&wrapper->children, method); - } - } - if (xParams) { - Q_PushTail(&wrapper->children, - XMLRPC_to_xml_element_worker(NULL, XMLRPC_RequestGetData(request), XMLRPC_RequestGetRequestType(request), 0)); - } - else { - /* Despite the spec, the xml-rpc list folk want me to send an empty params element */ - xml_element* params = xml_elem_new(); - params->name = strdup(ELEM_PARAMS); - Q_PushTail(&wrapper->children, params); - } - } - return wrapper; -} - diff --git a/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.h b/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.h deleted file mode 100644 index 234a153..0000000 --- a/php/xmlrpc/libxmlrpc/xml_to_xmlrpc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -#ifndef XML_TO_XMLRPC_H - #define XML_TO_XMLRPC_H - -#include "time.h" -#include "xmlrpc.h" - -XMLRPC_VALUE xml_element_to_XMLRPC_VALUE(xml_element* el); -XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST(XMLRPC_REQUEST request, xml_element* el); -xml_element* XMLRPC_VALUE_to_xml_element(XMLRPC_VALUE node); -xml_element* XMLRPC_REQUEST_to_xml_element(XMLRPC_REQUEST request); - -#endif /* XML_TO_XMLRPC_H */ diff --git a/php/xmlrpc/libxmlrpc/xmlrpc.c b/php/xmlrpc/libxmlrpc/xmlrpc.c deleted file mode 100644 index d5f3f7b..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc.c +++ /dev/null @@ -1,2963 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - - -/****h* ABOUT/xmlrpc - * NAME - * XMLRPC_VALUE - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * CREATION DATE - * 9/1999 - 10/2000 - * HISTORY - * $Log: xmlrpc.c,v $ - * Revision 1.6 2004/04/27 17:33:59 iliaa - * Removed C++ style comments. - * - * Revision 1.5 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.4 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.22 2002/03/09 23:15:44 danda - * add fault interrogation funcs - * - * Revision 1.21 2002/03/09 22:27:41 danda - * win32 build patches contributed by Jeff Lawson - * - * Revision 1.20 2002/02/13 20:58:50 danda - * patch to make source more windows friendly, contributed by Jeff Lawson - * - * Revision 1.19 2001/10/12 23:25:54 danda - * default to writing xmlrpc - * - * Revision 1.18 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 10/15/2000 -- danda -- adding robodoc documentation - * 08/2000 -- danda -- PHP C extension that uses XMLRPC - * 08/2000 -- danda -- support for two vocabularies: danda-rpc and xml-rpc - * 09/1999 -- danda -- Initial API, before I even knew of standard XMLRPC vocab. Response only. - * 07/2000 -- danda -- wrote new implementation to be compatible with xmlrpc standard and - * incorporated some ideas from ensor, most notably the separation of - * xml dom from xmlrpc api. - * 06/2000 -- danda -- played with expat-ensor from www.ensor.org. Cool, but some flaws. - * TODO - * PORTABILITY - * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just - * about anything with minor mods. - * NOTES - * Welcome to XMLRPC. For more info on the specification and history, see - * http://www.xmlrpc.org. - * - * This code aims to be a full-featured C implementation of XMLRPC. It does not - * have any networking code. Rather, it is intended to be plugged into apps - * or libraries with existing networking facilities, eg PHP, apache, perl, mozilla, - * home-brew application servers, etc. - * - * Usage Paradigm: - * The user of this library will typically be implementing either an XMLRPC server, - * an XMLRPC client, or both. The client will use the library to build an in-memory - * representation of a request, and then serialize (encode) that request into XML. The - * client will then send the XML to the server via external mechanism. The server will - * de-serialize the XML back into an binary representation, call the appropriate registered - * method -- thereby generating a response. The response will be serialized into XML and - * sent back to the client. The client will de-serialize it into memory, and can - * iterate through the results via API. - * - * Both the request and the response may consist of arbitrarily long, arbitrarily nested - * values. The values may be one of several types, as defined by XMLRPC_VALUE_TYPE. - * - * Features and Architecture: - * - The XML parsing (xml_element.c) is completely independent of the XMLRPC api. In fact, - * it can be used as a standalone dom implementation. - * - Because of this, the same XMLRPC data can be serialized into multiple xml vocabularies. - * It is simply a matter of writing a transport. So far, two transports have been defined. - * The default xmlrpc vocab (xml_to_xmlrpc.c), and simple-rpc (xml_to_dandarpc.c) which is - * proprietary, but imho more readable, and nice for proprietary legacy reasons. - * - Various output options, including: xml escaping via CDATA or entity, case folding, - * vocab version, and character encoding. - * - One to One mapping between C structures and actual values, unlike ensor which forces - * one to understand the arcana of the xmlrpc vocab. - * - support for mixed indexed/keyed vector types, making it more compatible with - * languages such as PHP. - * - quite speedy compared to implementations written in interpreted languages. Also, uses - * intelligent string handling, so not many strlen() calls, etc. - * - comprehensive API for manipulation of values - *******/ - - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include -#include -#include -#include - -#include "queue.h" -#include "xmlrpc.h" -#include "expat.h" -#include "base64.h" - -#include "xml_to_xmlrpc.h" -#include "xml_to_dandarpc.h" -#include "xml_to_soap.h" -#include "xml_element.h" -#include "xmlrpc_private.h" -#include "xmlrpc_introspection_private.h" -#include "system_methods_private.h" - - - -/*-********************* -* Begin Time Functions * -***********************/ - -static int date_from_ISO8601 (const char *text, time_t * value) { - struct tm tm; - int n; - int i; - char buf[18]; - - if (strchr (text, '-')) { - char *p = (char *) text, *p2 = buf; - while (p && *p) { - if (*p != '-') { - *p2 = *p; - p2++; - } - p++; - } - text = buf; - } - - - tm.tm_isdst = -1; - - if(strlen(text) < 17) { - return -1; - } - - n = 1000; - tm.tm_year = 0; - for(i = 0; i < 4; i++) { - tm.tm_year += (text[i]-'0')*n; - n /= 10; - } - n = 10; - tm.tm_mon = 0; - for(i = 0; i < 2; i++) { - tm.tm_mon += (text[i+4]-'0')*n; - n /= 10; - } - tm.tm_mon --; - - n = 10; - tm.tm_mday = 0; - for(i = 0; i < 2; i++) { - tm.tm_mday += (text[i+6]-'0')*n; - n /= 10; - } - - n = 10; - tm.tm_hour = 0; - for(i = 0; i < 2; i++) { - tm.tm_hour += (text[i+9]-'0')*n; - n /= 10; - } - - n = 10; - tm.tm_min = 0; - for(i = 0; i < 2; i++) { - tm.tm_min += (text[i+12]-'0')*n; - n /= 10; - } - - n = 10; - tm.tm_sec = 0; - for(i = 0; i < 2; i++) { - tm.tm_sec += (text[i+15]-'0')*n; - n /= 10; - } - - tm.tm_year -= 1900; - - *value = mktime(&tm); - - return 0; - -} - -static int date_to_ISO8601 (time_t value, char *buf, int length) { - struct tm *tm; - tm = localtime(&value); -#if 0 /* TODO: soap seems to favor this method. xmlrpc the latter. */ - return strftime (buf, length, "%Y-%m-%dT%H:%M:%SZ", tm); -#else - return strftime(buf, length, "%Y%m%dT%H:%M:%S", tm); -#endif -} - -/*-******************* -* End Time Functions * -*********************/ - - -/*-*************************** -* Begin XMLRPC_REQUEST funcs * -*****************************/ - -/****f* REQUEST/XMLRPC_RequestNew - * NAME - * XMLRPC_RequestNew - * SYNOPSIS - * XMLRPC_REQUEST XMLRPC_RequestNew() - * FUNCTION - * Creates a new XMLRPC_Request data struct - * INPUTS - * none - * SEE ALSO - * XMLRPC_RequestFree () - * SOURCE - */ -XMLRPC_REQUEST XMLRPC_RequestNew() { - XMLRPC_REQUEST xRequest = calloc(1, sizeof(STRUCT_XMLRPC_REQUEST)); - if(xRequest) { - simplestring_init(&xRequest->methodName); - } - return xRequest; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestFree - * NAME - * XMLRPC_RequestFree - * SYNOPSIS - * void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO) - * FUNCTION - * Free XMLRPC Request and all sub-values - * INPUTS - * request -- previously allocated request struct - * bFreeIO -- 1 = also free request value data, if any, 0 = ignore. - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_CleanupValue () - * SOURCE - */ -void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO) { - if(request) { - simplestring_free(&request->methodName); - - if(request->io && bFreeIO) { - XMLRPC_CleanupValue(request->io); - } - if(request->error) { - XMLRPC_CleanupValue(request->error); - } - my_free(request); - } -} - -/*******/ - -/* Set Method Name to call */ -/****f* REQUEST/XMLRPC_RequestSetMethodName - * NAME - * XMLRPC_RequestSetMethodName - * SYNOPSIS - * const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName) - * FUNCTION - * Set name of method to call with this request. - * INPUTS - * request -- previously allocated request struct - * methodName -- name of method - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestGetMethodName () - * XMLRPC_RequestFree () - * SOURCE - */ -const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName) { - if(request) { - simplestring_clear(&request->methodName); - simplestring_add(&request->methodName, methodName); - return request->methodName.str; - } - return NULL; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestGetMethodName - * NAME - * XMLRPC_RequestGetMethodName - * SYNOPSIS - * const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request) - * FUNCTION - * Get name of method called by this request - * INPUTS - * request -- previously allocated request struct - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestSetMethodName () - * XMLRPC_RequestFree () - * SOURCE - */ -const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request) { - return request ? request->methodName.str : NULL; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestSetRequestType - * NAME - * XMLRPC_RequestSetRequestType - * SYNOPSIS - * XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType(XMLRPC_REQUEST request, XMLRPC_REQUEST_TYPE type) - * FUNCTION - * A request struct may be allocated by a caller or by xmlrpc - * in response to a request. This allows setting the - * request type. - * INPUTS - * request -- previously allocated request struct - * type -- request type [xmlrpc_method_call | xmlrpc_method_response] - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestGetRequestType () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST_TYPE - * SOURCE - */ -XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType (XMLRPC_REQUEST request, - XMLRPC_REQUEST_TYPE type) { - if(request) { - request->request_type = type; - return request->request_type; - } - return xmlrpc_request_none; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestGetRequestType - * NAME - * XMLRPC_RequestGetRequestType - * SYNOPSIS - * XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request) - * FUNCTION - * A request struct may be allocated by a caller or by xmlrpc - * in response to a request. This allows setting the - * request type. - * INPUTS - * request -- previously allocated request struct - * RESULT - * type -- request type [xmlrpc_method_call | xmlrpc_method_response] - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestSetRequestType () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST_TYPE - * SOURCE - */ -XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request) { - return request ? request->request_type : xmlrpc_request_none; -} - -/*******/ - - -/****f* REQUEST/XMLRPC_RequestSetData - * NAME - * XMLRPC_RequestSetData - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data) - * FUNCTION - * Associates a block of xmlrpc data with the request. The - * data is *not* copied. A pointer is kept. The caller - * should be careful not to doubly free the data value, - * which may optionally be free'd by XMLRPC_RequestFree(). - * INPUTS - * request -- previously allocated request struct - * data -- previously allocated data struct - * RESULT - * XMLRPC_VALUE -- pointer to value stored, or NULL - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestGetData () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data) { - if(request && data) { - if (request->io) { - XMLRPC_CleanupValue (request->io); - } - request->io = XMLRPC_CopyValue(data); - return request->io; - } - return NULL; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestGetData - * NAME - * XMLRPC_RequestGetData - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request) - * FUNCTION - * Returns data associated with request, if any. - * INPUTS - * request -- previously allocated request struct - * RESULT - * XMLRPC_VALUE -- pointer to value stored, or NULL - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestSetData () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request) { - return request ? request->io : NULL; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestSetError - * NAME - * XMLRPC_RequestSetError - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_RequestSetError(XMLRPC_REQUEST request, XMLRPC_VALUE error) - * FUNCTION - * Associates a block of xmlrpc data, representing an error - * condition, with the request. - * INPUTS - * request -- previously allocated request struct - * error -- previously allocated error code or struct - * RESULT - * XMLRPC_VALUE -- pointer to value stored, or NULL - * NOTES - * This is a private function for usage by internals only. - * SEE ALSO - * XMLRPC_RequestGetError () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error) { - if (request && error) { - if (request->error) { - XMLRPC_CleanupValue (request->error); - } - request->error = XMLRPC_CopyValue (error); - return request->error; - } - return NULL; -} - -/*******/ - -/****f* REQUEST/XMLRPC_RequestGetError - * NAME - * XMLRPC_RequestGetError - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_RequestGetError(XMLRPC_REQUEST request) - * FUNCTION - * Returns error data associated with request, if any. - * INPUTS - * request -- previously allocated request struct - * RESULT - * XMLRPC_VALUE -- pointer to error value stored, or NULL - * NOTES - * This is a private function for usage by internals only. - * SEE ALSO - * XMLRPC_RequestSetError () - * XMLRPC_RequestFree () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request) { - return request ? request->error : NULL; -} - -/*******/ - - -/****f* REQUEST/XMLRPC_RequestSetOutputOptions - * NAME - * XMLRPC_RequestSetOutputOptions - * SYNOPSIS - * XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output) - * FUNCTION - * Sets output options used for generating XML. The output struct - * is copied, and may be freed by the caller. - * INPUTS - * request -- previously allocated request struct - * output -- output options struct initialized by caller - * RESULT - * XMLRPC_REQUEST_OUTPUT_OPTIONS -- pointer to value stored, or NULL - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestGetOutputOptions () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST - * XMLRPC_REQUEST_OUTPUT_OPTIONS - * SOURCE - */ -XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output) { - if(request && output) { - memcpy (&request->output, output, - sizeof (STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS)); - return &request->output; - } - return NULL; -} - -/*******/ - - -/****f* REQUEST/XMLRPC_RequestGetOutputOptions - * NAME - * XMLRPC_RequestGetOutputOptions - * SYNOPSIS - * XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request) - * FUNCTION - * Gets a pointer to output options used for generating XML. - * INPUTS - * request -- previously allocated request struct - * RESULT - * XMLRPC_REQUEST_OUTPUT_OPTIONS -- pointer to options stored, or NULL - * SEE ALSO - * XMLRPC_RequestNew () - * XMLRPC_RequestSetOutputOptions () - * XMLRPC_RequestFree () - * XMLRPC_REQUEST - * XMLRPC_REQUEST_OUTPUT_OPTIONS - * SOURCE - */ -XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request) { - return request ? &request->output : NULL; -} - -/*******/ - -/*-************************* -* End XMLRPC_REQUEST funcs * -***************************/ - - -/*-*************************** -* Begin Serializiation funcs * -*****************************/ - -/****f* SERIALIZE/XMLRPC_VALUE_ToXML - * NAME - * XMLRPC_VALUE_ToXML - * SYNOPSIS - * char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val) - * FUNCTION - * encode XMLRPC_VALUE into XML buffer. Note that the generated - * buffer will not contain a methodCall. - * INPUTS - * val -- previously allocated XMLRPC_VALUE - * buf_len -- length of returned buffer, if not null - * RESULT - * char* -- newly allocated buffer containing XML. - * It is the caller's responsibility to free it. - * SEE ALSO - * XMLRPC_REQUEST_ToXML () - * XMLRPC_VALUE_FromXML () - * XMLRPC_Free () - * XMLRPC_VALUE - * SOURCE - */ -char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val, int* buf_len) { - xml_element *root_elem = XMLRPC_VALUE_to_xml_element(val); - char* pRet = NULL; - - if(root_elem) { - pRet = xml_elem_serialize_to_string(root_elem, NULL, buf_len); - xml_elem_free(root_elem); - } - return pRet; -} - -/*******/ - -/****f* SERIALIZE/XMLRPC_REQUEST_ToXML - * NAME - * XMLRPC_REQUEST_ToXML - * SYNOPSIS - * char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request) - * FUNCTION - * encode XMLRPC_REQUEST into XML buffer - * INPUTS - * request -- previously allocated XMLRPC_REQUEST - * buf_len -- size of returned buf, if not null - * RESULT - * char* -- newly allocated buffer containing XML. - * It is the caller's responsibility to free it. - * SEE ALSO - * XMLRPC_REQUEST_ToXML () - * XMLRPC_REQUEST_FromXML () - * XMLRPC_Free () - * XMLRPC_VALUE_ToXML () - * XMLRPC_REQUEST - * SOURCE - */ -char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int* buf_len) { - char* pRet = NULL; - if (request) { - xml_element *root_elem = NULL; - if (request->output.version == xmlrpc_version_simple) { - root_elem = DANDARPC_REQUEST_to_xml_element (request); - } - else if (request->output.version == xmlrpc_version_1_0 || - request->output.version == xmlrpc_version_none) { - root_elem = XMLRPC_REQUEST_to_xml_element (request); - } - else if (request->output.version == xmlrpc_version_soap_1_1) { - root_elem = SOAP_REQUEST_to_xml_element (request); - } - - if(root_elem) { - pRet = - xml_elem_serialize_to_string (root_elem, - &request->output.xml_elem_opts, - buf_len); - xml_elem_free(root_elem); - } - } - return pRet; -} - -/*******/ - -/****f* SERIALIZE/XMLRPC_VALUE_FromXML - * NAME - * XMLRPC_VALUE_FromXML - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_VALUE_FromXML(const char* in_buf, int le - * FUNCTION - * Retrieve XMLRPC_VALUE from XML buffer. Note that this will - * ignore any methodCall. See XMLRPC_REQUEST_FromXML - * INPUTS - * in_buf -- character buffer containing XML - * len -- length of buffer - * RESULT - * XMLRPC_VALUE -- newly allocated data, or NULL if error. Should - * be free'd by caller. - * SEE ALSO - * XMLRPC_VALUE_ToXML () - * XMLRPC_REQUEST_FromXML () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_VALUE_FromXML (const char *in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options) { - XMLRPC_VALUE xResponse = NULL; - XMLRPC_REQUEST req = XMLRPC_REQUEST_FromXML(in_buf, len, in_options); - - if(req) { - xResponse = req->io; - XMLRPC_RequestFree(req, 0); - } - return xResponse; -} - -/*******/ - -/* map parser errors to standard xml-rpc errors */ -static XMLRPC_VALUE map_expat_errors(XML_ELEM_ERROR error) { - XMLRPC_VALUE xReturn = NULL; - if(error) { - XMLRPC_ERROR_CODE code; - char buf[1024]; - snprintf(buf, sizeof(buf), - "error occurred at line %ld, column %ld, byte index %ld", - error->line, error->column, error->byte_index); - - /* expat specific errors */ - switch(error->parser_code) { - case XML_ERROR_UNKNOWN_ENCODING: - code = xmlrpc_error_parse_unknown_encoding; - break; - case XML_ERROR_INCORRECT_ENCODING: - code = xmlrpc_error_parse_bad_encoding; - break; - default: - code = xmlrpc_error_parse_xml_syntax; - break; - } - xReturn = XMLRPC_UtilityCreateFault(code, buf); - } - return xReturn; -} - -/****f* SERIALIZE/XMLRPC_REQUEST_FromXML - * NAME - * XMLRPC_REQUEST_FromXML - * SYNOPSIS - * XMLRPC_REQUEST XMLRPC_REQUEST_FromXML(const char* in_buf, int le - * FUNCTION - * Retrieve XMLRPC_REQUEST from XML buffer - * INPUTS - * in_buf -- character buffer containing XML - * len -- length of buffer - * RESULT - * XMLRPC_REQUEST -- newly allocated data, or NULL if error. Should - * be free'd by caller. - * SEE ALSO - * XMLRPC_REQUEST_ToXML () - * XMLRPC_VALUE_FromXML () - * XMLRPC_REQUEST - * SOURCE - */ -XMLRPC_REQUEST XMLRPC_REQUEST_FromXML (const char *in_buf, int len, - XMLRPC_REQUEST_INPUT_OPTIONS in_options) { - XMLRPC_REQUEST request = XMLRPC_RequestNew(); - STRUCT_XML_ELEM_ERROR error = {0}; - - if(request) { - xml_element *root_elem = - xml_elem_parse_buf (in_buf, len, - (in_options ? &in_options->xml_elem_opts : NULL), - &error); - - if(root_elem) { - if(!strcmp(root_elem->name, "simpleRPC")) { - request->output.version = xmlrpc_version_simple; - xml_element_to_DANDARPC_REQUEST(request, root_elem); - } - else if (!strcmp (root_elem->name, "SOAP-ENV:Envelope")) { - request->output.version = xmlrpc_version_soap_1_1; - xml_element_to_SOAP_REQUEST (request, root_elem); - } - else { - request->output.version = xmlrpc_version_1_0; - xml_element_to_XMLRPC_REQUEST(request, root_elem); - } - xml_elem_free(root_elem); - } - else { - if(error.parser_error) { - XMLRPC_RequestSetError (request, map_expat_errors (&error)); - } - } - } - - return request; -} - -/*******/ - -/*-************************ -* End Serialization Funcs * -**************************/ - - - -/****f* VALUE/XMLRPC_CreateValueEmpty - * NAME - * XMLRPC_CreateValueEmpty - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueEmpty () - * FUNCTION - * Create an XML value to be used/modified elsewhere. - * INPUTS - * RESULT - * XMLRPC_VALUE. The new value, or NULL on failure. - * SEE ALSO - * XMLRPC_CleanupValue () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueEmpty() { - XMLRPC_VALUE v = calloc(1, sizeof(STRUCT_XMLRPC_VALUE)); - if(v) { -#ifdef XMLRPC_DEBUG_REFCOUNT - printf ("calloc'd 0x%x\n", v); -#endif - v->type = xmlrpc_empty; - simplestring_init(&v->id); - simplestring_init(&v->str); - } - return v; -} - -/*******/ - -/****f* VALUE/XMLRPC_SetValueID_Case - * NAME - * XMLRPC_SetValueID_Case - * SYNOPSIS - * const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case) - * FUNCTION - * Assign an ID (key) to an XMLRPC value. - * INPUTS - * value The xml value who's ID we will set. - * id The desired new id. - * len length of id string if known, or 0 if unknown. - * id_case one of XMLRPC_CASE - * RESULT - * const char* pointer to the newly allocated id string, or NULL - * SEE ALSO - * XMLRPC_SetValueID () - * XMLRPC_GetValueID () - * XMLRPC_VALUE - * XMLRPC_CASE - * SOURCE - */ -const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case) { - const char* pRetval = NULL; - if(value) { - if(id) { - simplestring_clear(&value->id); - (len > 0) ? simplestring_addn(&value->id, id, len) : - simplestring_add(&value->id, id); - - /* upper or lower case string in place if required. could be a seperate func. */ - if(id_case == xmlrpc_case_lower || id_case == xmlrpc_case_upper) { - int i; - for(i = 0; i < value->id.len; i++) { - value->id.str[i] = - (id_case == - xmlrpc_case_lower) ? tolower (value->id. - str[i]) : toupper (value-> - id. - str[i]); - } - } - - pRetval = value->id.str; - -#ifdef XMLRPC_DEBUG_REFCOUNT - printf("set value id: %s\n", pRetval); -#endif - } - } - - return pRetval; -} - -/*******/ - - -/****f* VALUE/XMLRPC_SetValueString - * NAME - * XMLRPC_SetValueString - * SYNOPSIS - * const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* val, int len) - * FUNCTION - * Assign a string value to an XMLRPC_VALUE, and set it to type xmlrpc_string - * INPUTS - * value The xml value who's ID we will set. - * val The desired new string val. - * len length of val string if known, or 0 if unknown. - * RESULT - * const char* pointer to the newly allocated value string, or NULL - * SEE ALSO - * XMLRPC_GetValueString () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* val, int len) { - char *pRetval = NULL; - if(value && val) { - simplestring_clear(&value->str); - (len > 0) ? simplestring_addn(&value->str, val, len) : - simplestring_add(&value->str, val); - value->type = xmlrpc_string; - pRetval = (char *)value->str.str; - } - - return pRetval; -} - -/*******/ - -/****f* VALUE/XMLRPC_SetValueInt - * NAME - * XMLRPC_SetValueInt - * SYNOPSIS - * void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val) - * FUNCTION - * Assign an int value to an XMLRPC_VALUE, and set it to type xmlrpc_int - * INPUTS - * value The xml value who's ID we will set. - * val The desired new integer value - * RESULT - * SEE ALSO - * XMLRPC_GetValueInt () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val) { - if(value) { - value->type = xmlrpc_int; - value->i = val; - } -} - -/*******/ - -/****f* VALUE/XMLRPC_SetValueBoolean - * NAME - * XMLRPC_SetValueBoolean - * SYNOPSIS - * void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val) - * FUNCTION - * Assign a boolean value to an XMLRPC_VALUE, and set it to type xmlrpc_boolean - * INPUTS - * value The xml value who's value we will set. - * val The desired new boolean value. [0 | 1] - * RESULT - * SEE ALSO - * XMLRPC_GetValueBoolean () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val) { - if(value) { - value->type = xmlrpc_boolean; - value->i = val ? 1 : 0; - } -} - -/*******/ - - -/****f* VECTOR/XMLRPC_SetIsVector - * NAME - * XMLRPC_SetIsVector - * SYNOPSIS - * int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type) - * FUNCTION - * Set the XMLRPC_VALUE to be a vector (list) type. The vector may be one of - * [xmlrpc_array | xmlrpc_struct | xmlrpc_mixed]. An array has only index values. - * A struct has key/val pairs. Mixed allows both index and key/val combinations. - * INPUTS - * value The xml value who's vector type we will set - * type New type of vector as enumerated by XMLRPC_VECTOR_TYPE - * RESULT - * int 1 if successful, 0 otherwise - * SEE ALSO - * XMLRPC_GetValueType () - * XMLRPC_GetVectorType () - * XMLRPC_VALUE - * XMLRPC_VECTOR_TYPE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type) { - int bSuccess = 0; - - if (value) { - /* we can change the type so long as nothing is currently stored. */ - if(value->type == xmlrpc_vector) { - if(value->v) { - if(!Q_Size(value->v->q)) { - value->v->type = type; - } - } - } - else { - value->v = calloc(1, sizeof(STRUCT_XMLRPC_VECTOR)); - if(value->v) { - value->v->q = (queue*)malloc(sizeof(queue)); - if(value->v->q) { - Q_Init(value->v->q); - value->v->type = type; - value->type = xmlrpc_vector; - bSuccess = 1; - } - } - } - } - - return bSuccess; -} - -/*******/ - -/****f* VECTOR/XMLRPC_CreateVector - * NAME - * XMLRPC_CreateVector - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type) - * FUNCTION - * Create a new vector and optionally set an id. - * INPUTS - * id The id of the vector, or NULL - * type New type of vector as enumerated by XMLRPC_VECTOR_TYPE - * RESULT - * XMLRPC_VALUE The new vector, or NULL on failure. - * SEE ALSO - * XMLRPC_CreateValueEmpty () - * XMLRPC_SetIsVector () - * XMLRPC_GetValueType () - * XMLRPC_GetVectorType () - * XMLRPC_VALUE - * XMLRPC_VECTOR_TYPE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type) { - XMLRPC_VALUE val = NULL; - - val = XMLRPC_CreateValueEmpty(); - if(val) { - if(XMLRPC_SetIsVector(val, type)) { - if(id) { - const char *pSVI = NULL; - - pSVI = XMLRPC_SetValueID(val, id, 0); - if(NULL == pSVI) { - val = NULL; - } - } - } - else { - val = NULL; - } - } - return val; -} - -/*******/ - - -/* Not yet implemented. - * - * This should use a hash to determine if a given target id has already - * been appended. - * - * Alternately, it could walk the entire vector, but that could be quite - * slow for very large lists. - */ -static int isDuplicateEntry(XMLRPC_VALUE target, XMLRPC_VALUE source) { - return 0; -} - -/****f* VECTOR/XMLRPC_AddValueToVector - * NAME - * XMLRPC_AddValueToVector - * SYNOPSIS - * int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source) - * FUNCTION - * Add (append) an existing XMLRPC_VALUE to a vector. - * INPUTS - * target The target vector - * source The source value to append - * RESULT - * int 1 if successful, else 0 - * SEE ALSO - * XMLRPC_AddValuesToVector () - * XMLRPC_VectorGetValueWithID_Case () - * XMLRPC_VALUE - * NOTES - * The function will fail and return 0 if an attempt is made to add - * a value with an ID into a vector of type xmlrpc_vector_array. Such - * values can only be added to xmlrpc_vector_struct. - * SOURCE - */ -int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source) { - if(target && source) { - if(target->type == xmlrpc_vector && target->v && - target->v->q && target->v->type != xmlrpc_vector_none) { - - /* guard against putting value of unknown type into vector */ - switch(source->type) { - case xmlrpc_empty: - case xmlrpc_nil: - case xmlrpc_base64: - case xmlrpc_boolean: - case xmlrpc_datetime: - case xmlrpc_double: - case xmlrpc_int: - case xmlrpc_string: - case xmlrpc_vector: - /* Guard against putting a key/val pair into an array vector */ - if( !(source->id.len && target->v->type == xmlrpc_vector_array) ) { - if (isDuplicateEntry (target, source) - || Q_PushTail (target->v->q, XMLRPC_CopyValue (source))) { - return 1; - } - } - else { - fprintf (stderr, - "xmlrpc: attempted to add key/val pair to vector of type array\n"); - } - break; - default: - fprintf (stderr, - "xmlrpc: attempted to add value of unknown type to vector\n"); - break; - } - } - } - return 0; -} - -/*******/ - - -/****f* VECTOR/XMLRPC_AddValuesToVector - * NAME - * XMLRPC_AddValuesToVector - * SYNOPSIS - * XMLRPC_AddValuesToVector ( target, val1, val2, val3, val(n), 0 ) - * XMLRPC_AddValuesToVector( XMLRPC_VALUE, ... ) - * FUNCTION - * Add (append) a series of existing XMLRPC_VALUE to a vector. - * INPUTS - * target The target vector - * ... The source value(s) to append. The last item *must* be 0. - * RESULT - * int 1 if successful, else 0 - * SEE ALSO - * XMLRPC_AddValuesToVector () - * XMLRPC_VectorGetValueWithID_Case () - * XMLRPC_VALUE - * NOTES - * This function may actually return failure after it has already modified - * or added items to target. You can not trust the state of target - * if this function returns failure. - * SOURCE - */ -int XMLRPC_AddValuesToVector(XMLRPC_VALUE target, ...) { - int iRetval = 0; - - if(target) { - if(target->type == xmlrpc_vector) { - XMLRPC_VALUE v = NULL; - va_list vl; - - va_start(vl, target); - - do { - v = va_arg(vl, XMLRPC_VALUE); - if(v) { - if(!XMLRPC_AddValueToVector(target, v)) { - iRetval = 0; - break; - } - } - } - while (v); - - va_end(vl); - - if(NULL == v) { - iRetval = 1; - } - } - } - return iRetval; -} - -/*******/ - - -/****f* VECTOR/XMLRPC_VectorGetValueWithID_Case - * NAME - * XMLRPC_VectorGetValueWithID_Case - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case(XMLRPC_VALUE vector, const char* id, XMLRPC_CASE_COMPARISON id_case) - * FUNCTION - * Get value from vector matching id (key) - * INPUTS - * vector The source vector - * id The key to find - * id_case Rule for how to match key - * RESULT - * int 1 if successful, else 0 - * SEE ALSO - * XMLRPC_SetValueID_Case () - * XMLRPC_VALUE - * XMLRPC_CASE_COMPARISON - * SOURCE - */ -XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case (XMLRPC_VALUE vector, const char *id, - XMLRPC_CASE_COMPARISON id_case) { - if(vector && vector->v && vector->v->q) { - q_iter qi = Q_Iter_Head_F(vector->v->q); - - while(qi) { - XMLRPC_VALUE xIter = Q_Iter_Get_F(qi); - if(xIter && xIter->id.str) { - if(id_case == xmlrpc_case_sensitive) { - if(!strcmp(xIter->id.str, id)) { - return xIter; - } - } - else if(id_case == xmlrpc_case_insensitive) { - if(!strcasecmp(xIter->id.str, id)) { - return xIter; - } - } - } - qi = Q_Iter_Next_F(qi); - } - } - return NULL; -} - -/*******/ - - -int XMLRPC_VectorRemoveValue(XMLRPC_VALUE vector, XMLRPC_VALUE value) { - if(vector && vector->v && vector->v->q && value) { - q_iter qi = Q_Iter_Head_F(vector->v->q); - - while(qi) { - XMLRPC_VALUE xIter = Q_Iter_Get_F(qi); - if(xIter == value) { - XMLRPC_CleanupValue(xIter); - Q_Iter_Del(vector->v->q, qi); - return 1; - } - qi = Q_Iter_Next_F(qi); - } - } - return 0; -} - - -/****f* VALUE/XMLRPC_CreateValueString - * NAME - * XMLRPC_CreateValueString - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len) - * FUNCTION - * Create an XMLRPC_VALUE, and assign a string to it - * INPUTS - * id The id of the value, or NULL - * val The desired new string val. - * len length of val string if known, or 0 if unknown. - * RESULT - * newly allocated XMLRPC_VALUE, or NULL - * SEE ALSO - * XMLRPC_GetValueString () - * XMLRPC_CreateValueEmpty () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* val, int len) { - XMLRPC_VALUE value = NULL; - if(val) { - value = XMLRPC_CreateValueEmpty(); - if(value) { - XMLRPC_SetValueString(value, val, len); - if(id) { - XMLRPC_SetValueID(value, id, 0); - } - } - } - return value; -} - -/*******/ - -/****f* VALUE/XMLRPC_CreateValueInt - * NAME - * XMLRPC_CreateValueInt - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i) - * FUNCTION - * Create an XMLRPC_VALUE, and assign an int to it - * INPUTS - * id The id of the value, or NULL - * i The desired new int val. - * RESULT - * newly allocated XMLRPC_VALUE, or NULL - * SEE ALSO - * XMLRPC_GetValueInt () - * XMLRPC_CreateValueEmpty () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueInt(val, i); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - -/****f* VALUE/XMLRPC_CreateValueBoolean - * NAME - * XMLRPC_CreateValueBoolean - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i) - * FUNCTION - * Create an XMLRPC_VALUE, and assign an int to it - * INPUTS - * id The id of the value, or NULL - * i The desired new int val. - * RESULT - * newly allocated XMLRPC_VALUE, or NULL - * SEE ALSO - * XMLRPC_GetValueBoolean () - * XMLRPC_CreateValueEmpty () - * XMLRPC_VALUE - * XMLRPC_VALUE_TYPE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int i) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueBoolean(val, i); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - - -/****f* VALUE/XMLRPC_CleanupValue - * NAME - * XMLRPC_CleanupValue - * SYNOPSIS - * void XMLRPC_CleanupValue(XMLRPC_VALUE value) - * FUNCTION - * Frees all memory allocated for an XMLRPC_VALUE and any of its children (if a vector) - * INPUTS - * value The id of the value to be cleaned up. - * RESULT - * void - * NOTES - * Normally this function will be called for the topmost vector, thus free-ing - * all children. If a child of a vector is free'd first, results are undefined. - * Failure to call this function *will* cause memory leaks. - * - * Also, this function is implemented using reference counting. Thus a value - * may be added and freed from multiple parents so long as a reference is added - * first using XMLRPC_CopyValue() - * SEE ALSO - * XMLRPC_RequestFree () - * XMLRPC_CreateValueEmpty () - * XMLRPC_CopyValue() - * XMLRPC_VALUE - * SOURCE - */ -void XMLRPC_CleanupValue(XMLRPC_VALUE value) { - if(value) { - if(value->iRefCount > 0) { - value->iRefCount --; - } - -#ifdef XMLRPC_DEBUG_REFCOUNT - if(value->id.str) { - printf ("decremented refcount of %s, now %i\n", value->id.str, - value->iRefCount); - } - else { - printf ("decremented refcount of 0x%x, now %i\n", value, - value->iRefCount); - } -#endif - - if(value->type == xmlrpc_vector) { - if(value->v) { - if(value->iRefCount == 0) { - XMLRPC_VALUE cur = (XMLRPC_VALUE)Q_Head(value->v->q); - while( cur ) { - XMLRPC_CleanupValue(cur); - - /* Make sure some idiot didn't include a vector as a child of itself - * and thus it would have already free'd these. - */ - if(value->v && value->v->q) { - cur = Q_Next(value->v->q); - } - else { - break; - } - } - - Q_Destroy(value->v->q); - my_free(value->v->q); - my_free(value->v); - } - } - } - - - if(value->iRefCount == 0) { - - /* guard against freeing invalid types */ - switch(value->type) { - case xmlrpc_empty: - case xmlrpc_base64: - case xmlrpc_boolean: - case xmlrpc_datetime: - case xmlrpc_double: - case xmlrpc_int: - case xmlrpc_string: - case xmlrpc_vector: -#ifdef XMLRPC_DEBUG_REFCOUNT - if(value->id.str) { - printf("free'd %s\n", value->id.str); - } - else { - printf("free'd 0x%x\n", value); - } -#endif - simplestring_free(&value->id); - simplestring_free(&value->str); - - memset(value, 0, sizeof(STRUCT_XMLRPC_VALUE)); - my_free(value); - break; - default: - fprintf (stderr, - "xmlrpc: attempted to free value of invalid type\n"); - break; - } - } - } -} - -/*******/ - - -/****f* VALUE/XMLRPC_SetValueDateTime - * NAME - * XMLRPC_SetValueDateTime - * SYNOPSIS - * void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time) - * FUNCTION - * Assign time value to XMLRPC_VALUE - * INPUTS - * value The target XMLRPC_VALUE - * time The desired new unix time value (time_t) - * RESULT - * void - * SEE ALSO - * XMLRPC_GetValueDateTime () - * XMLRPC_SetValueDateTime_ISO8601 () - * XMLRPC_CreateValueDateTime () - * XMLRPC_VALUE - * SOURCE - */ -void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time) { - if(value) { - char timeBuf[30]; - value->type = xmlrpc_datetime; - value->i = time; - - timeBuf[0] = 0; - - date_to_ISO8601(time, timeBuf, sizeof(timeBuf)); - - if(timeBuf[0]) { - simplestring_clear(&value->str); - simplestring_add(&value->str, timeBuf); - } - } -} - -/*******/ - -/****f* VALUE/XMLRPC_CopyValue - * NAME - * XMLRPC_CopyValue - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value) - * FUNCTION - * Make a copy (reference) of an XMLRPC_VALUE - * INPUTS - * value The target XMLRPC_VALUE - * RESULT - * XMLRPC_VALUE -- address of the copy - * SEE ALSO - * XMLRPC_CleanupValue () - * XMLRPC_DupValueNew () - * NOTES - * This function is implemented via reference counting, so the - * returned value is going to be the same as the passed in value. - * The value must be freed the same number of times it is copied - * or there will be a memory leak. - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value) { - if(value) { - value->iRefCount ++; -#ifdef XMLRPC_DEBUG_REFCOUNT - if(value->id.str) { - printf ("incremented refcount of %s, now %i\n", value->id.str, - value->iRefCount); - } - else { - printf ("incremented refcount of 0x%x, now %i\n", value, - value->iRefCount); - } -#endif - } - return value; -} - -/*******/ - - -/****f* VALUE/XMLRPC_DupValueNew - * NAME - * XMLRPC_DupValueNew - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE value) - * FUNCTION - * Make a duplicate (non reference) of an XMLRPC_VALUE with newly allocated mem. - * INPUTS - * value The source XMLRPC_VALUE to duplicate - * RESULT - * XMLRPC_VALUE -- address of the duplicate value - * SEE ALSO - * XMLRPC_CleanupValue () - * XMLRPC_CopyValue () - * NOTES - * Use this when function when you need to modify the contents of - * the copied value seperately from the original. - * - * this function is recursive, thus the value and all of its children - * (if any) will be duplicated. - * SOURCE - */ -XMLRPC_VALUE XMLRPC_DupValueNew (XMLRPC_VALUE xSource) { - XMLRPC_VALUE xReturn = NULL; - if (xSource) { - xReturn = XMLRPC_CreateValueEmpty (); - if (xSource->id.len) { - XMLRPC_SetValueID (xReturn, xSource->id.str, xSource->id.len); - } - - switch (xSource->type) { - case xmlrpc_int: - case xmlrpc_boolean: - XMLRPC_SetValueInt (xReturn, xSource->i); - break; - case xmlrpc_string: - case xmlrpc_base64: - XMLRPC_SetValueString (xReturn, xSource->str.str, xSource->str.len); - break; - case xmlrpc_datetime: - XMLRPC_SetValueDateTime (xReturn, xSource->i); - break; - case xmlrpc_double: - XMLRPC_SetValueDouble (xReturn, xSource->d); - break; - case xmlrpc_vector: - { - q_iter qi = Q_Iter_Head_F (xSource->v->q); - XMLRPC_SetIsVector (xReturn, xSource->v->type); - - while (qi) { - XMLRPC_VALUE xIter = Q_Iter_Get_F (qi); - XMLRPC_AddValueToVector (xReturn, XMLRPC_DupValueNew (xIter)); - qi = Q_Iter_Next_F (qi); - } - } - break; - default: - break; - } - } - return xReturn; -} - -/*******/ - - - -/****f* VALUE/XMLRPC_CreateValueDateTime - * NAME - * XMLRPC_CreateValueDateTime - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time) - * FUNCTION - * Create new datetime value from time_t - * INPUTS - * id id of the new value, or NULL - * time The desired unix time value (time_t) - * RESULT - * void - * SEE ALSO - * XMLRPC_GetValueDateTime () - * XMLRPC_SetValueDateTime () - * XMLRPC_CreateValueDateTime_ISO8601 () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueDateTime(val, time); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - - -/****f* VALUE/XMLRPC_SetValueDateTime_ISO8601 - * NAME - * XMLRPC_SetValueDateTime_ISO8601 - * SYNOPSIS - * void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s) - * FUNCTION - * Set datetime value from IS08601 encoded string - * INPUTS - * value The target XMLRPC_VALUE - * s The desired new time value - * RESULT - * void - * BUGS - * This function currently attempts to convert the time string to a valid unix time - * value before passing it. Behavior when the string is invalid or out of range - * is not well defined, but will probably result in Jan 1, 1970 (0) being passed. - * SEE ALSO - * XMLRPC_GetValueDateTime_ISO8601 () - * XMLRPC_CreateValueDateTime_ISO8601 () - * XMLRPC_CreateValueDateTime () - * XMLRPC_VALUE - * SOURCE - */ -void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s) { - if(value) { - time_t time_val = 0; - if(s) { - date_from_ISO8601(s, &time_val); - XMLRPC_SetValueDateTime(value, time_val); - } - } -} - -/*******/ - -/****f* VALUE/XMLRPC_CreateValueDateTime_ISO8601 - * NAME - * XMLRPC_CreateValueDateTime_ISO8601 - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s) - * FUNCTION - * Create datetime value from IS08601 encoded string - * INPUTS - * id The id of the new value, or NULL - * s The desired new time value - * RESULT - * newly allocated XMLRPC_VALUE, or NULL if no value created. - * BUGS - * See XMLRPC_SetValueDateTime_ISO8601 () - * SEE ALSO - * XMLRPC_GetValueDateTime_ISO8601 () - * XMLRPC_SetValueDateTime_ISO8601 () - * XMLRPC_CreateValueDateTime () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueDateTime_ISO8601(val, s); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - - -/****f* VALUE/XMLRPC_SetValueBase64 - * NAME - * XMLRPC_SetValueBase64 - * SYNOPSIS - * void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len) - * FUNCTION - * Set base64 value. Base64 is useful for transferring binary data, such as an image. - * INPUTS - * value The target XMLRPC_VALUE - * s The desired new binary value - * len The length of s, or NULL. If buffer is not null terminated, len *must* be passed. - * RESULT - * void - * NOTES - * Data is set/stored/retrieved as passed in, but is base64 encoded for XML transfer, and - * decoded on the other side. This is transparent to the caller. - * SEE ALSO - * XMLRPC_GetValueBase64 () - * XMLRPC_CreateValueBase64 () - * XMLRPC_VALUE - * SOURCE - */ -void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len) { - if(value && s) { - simplestring_clear(&value->str); - (len > 0) ? simplestring_addn(&value->str, s, len) : - simplestring_add(&value->str, s); - value->type = xmlrpc_base64; - } -} - -/*******/ - - -/****f* VALUE/XMLRPC_CreateValueBase64 - * NAME - * XMLRPC_CreateValueBase64 - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len) - * FUNCTION - * Create base64 value. Base64 is useful for transferring binary data, such as an image. - * INPUTS - * id id of the new value, or NULL - * s The desired new binary value - * len The length of s, or NULL. If buffer is not null terminated, len *must* be passed. - * RESULT - * newly allocated XMLRPC_VALUE, or NULL if error - * NOTES - * See XMLRPC_SetValueBase64 () - * SEE ALSO - * XMLRPC_GetValueBase64 () - * XMLRPC_SetValueBase64 () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueBase64(val, s, len); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - -/****f* VALUE/XMLRPC_SetValueDouble - * NAME - * XMLRPC_SetValueDouble - * SYNOPSIS - * void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val) - * FUNCTION - * Set double (floating point) value. - * INPUTS - * value The target XMLRPC_VALUE - * val The desired new double value - * RESULT - * void - * SEE ALSO - * XMLRPC_GetValueDouble () - * XMLRPC_CreateValueDouble () - * XMLRPC_VALUE - * SOURCE - */ -void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val) { - if(value) { - value->type = xmlrpc_double; - value->d = val; - } -} - -/*******/ - -/****f* VALUE/XMLRPC_CreateValueDouble - * NAME - * XMLRPC_CreateValueDouble - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double d) - * FUNCTION - * Create double (floating point) value. - * INPUTS - * id id of the newly created value, or NULL - * d The desired new double value - * RESULT - * void - * SEE ALSO - * XMLRPC_GetValueDouble () - * XMLRPC_CreateValueDouble () - * XMLRPC_VALUE - * SOURCE - */ -XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double d) { - XMLRPC_VALUE val = XMLRPC_CreateValueEmpty(); - if(val) { - XMLRPC_SetValueDouble(val, d); - if(id) { - XMLRPC_SetValueID(val, id, 0); - } - } - return val; -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueString - * NAME - * XMLRPC_GetValueString - * SYNOPSIS - * const char* XMLRPC_GetValueString(XMLRPC_VALUE value) - * FUNCTION - * retrieve string value - * INPUTS - * value source XMLRPC_VALUE of type xmlrpc_string - * RESULT - * void - * SEE ALSO - * XMLRPC_SetValueString () - * XMLRPC_GetValueType () - * XMLRPC_VALUE - * SOURCE - */ -const char* XMLRPC_GetValueString(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_string) ? value->str.str : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueStringLen - * NAME - * XMLRPC_GetValueStringLen - * SYNOPSIS - * int XMLRPC_GetValueStringLen(XMLRPC_VALUE value) - * FUNCTION - * determine length of string value - * INPUTS - * value XMLRPC_VALUE of type xmlrpc_string - * RESULT - * length of string, or 0 - * NOTES - * SEE ALSO - * XMLRPC_SetValueString () - * XMLRPC_GetValueString () - * SOURCE - */ -int XMLRPC_GetValueStringLen(XMLRPC_VALUE value) { - return ((value) ? value->str.len : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueInt - * NAME - * XMLRPC_GetValueInt - * SYNOPSIS - * int XMLRPC_GetValueInt(XMLRPC_VALUE value) - * FUNCTION - * retrieve integer value. - * INPUTS - * value XMLRPC_VALUE of type xmlrpc_int - * RESULT - * integer value or 0 if value is not valid int - * NOTES - * use XMLRPC_GetValueType () to be sure if 0 is real return value or not - * SEE ALSO - * XMLRPC_SetValueInt () - * XMLRPC_CreateValueInt () - * SOURCE - */ -int XMLRPC_GetValueInt(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_int) ? value->i : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueBoolean - * NAME - * XMLRPC_GetValueBoolean - * SYNOPSIS - * int XMLRPC_GetValueBoolean(XMLRPC_VALUE value) - * FUNCTION - * retrieve boolean value. - * INPUTS - * XMLRPC_VALUE of type xmlrpc_boolean - * RESULT - * boolean value or 0 if value is not valid boolean - * NOTES - * use XMLRPC_GetValueType() to be sure if 0 is real value or not - * SEE ALSO - * XMLRPC_SetValueBoolean () - * XMLRPC_CreateValueBoolean () - * SOURCE - */ -int XMLRPC_GetValueBoolean(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_boolean) ? value->i : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueDouble - * NAME - * XMLRPC_GetValueDouble - * SYNOPSIS - * double XMLRPC_GetValueDouble(XMLRPC_VALUE value) - * FUNCTION - * retrieve double value - * INPUTS - * XMLRPC_VALUE of type xmlrpc_double - * RESULT - * double value or 0 if value is not valid double. - * NOTES - * use XMLRPC_GetValueType() to be sure if 0 is real value or not - * SEE ALSO - * XMLRPC_SetValueDouble () - * XMLRPC_CreateValueDouble () - * SOURCE - */ -double XMLRPC_GetValueDouble(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_double) ? value->d : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueBase64 - * NAME - * XMLRPC_GetValueBase64 - * SYNOPSIS - * const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value) - * FUNCTION - * retrieve binary value - * INPUTS - * XMLRPC_VALUE of type xmlrpc_base64 - * RESULT - * pointer to binary value or 0 if value is not valid. - * SEE ALSO - * XMLRPC_SetValueBase64 () - * XMLRPC_CreateValueBase64 () - * NOTES - * Call XMLRPC_GetValueStringLen() to retrieve real length of binary data. strlen() - * will not be accurate, as returned data may contain embedded nulls. - * SOURCE - */ -const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_base64) ? value->str.str : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueDateTime - * NAME - * XMLRPC_GetValueDateTime - * SYNOPSIS - * time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value) - * FUNCTION - * retrieve time_t value - * INPUTS - * XMLRPC_VALUE of type xmlrpc_datetime - * RESULT - * time_t value or 0 if value is not valid datetime. - * NOTES - * use XMLRPC_GetValueType() to be sure if 0 is real value or not - * SEE ALSO - * XMLRPC_SetValueDateTime () - * XMLRPC_GetValueDateTime_ISO8601 () - * XMLRPC_CreateValueDateTime () - * SOURCE - */ -time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value) { - return (time_t)((value && value->type == xmlrpc_datetime) ? value->i : 0); -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueDateTime_IOS8601 - * NAME - * XMLRPC_GetValueDateTime_IOS8601 - * SYNOPSIS - * const char* XMLRPC_GetValueDateTime_IOS8601(XMLRPC_VALUE value) - * FUNCTION - * retrieve ISO8601 formatted time value - * INPUTS - * XMLRPC_VALUE of type xmlrpc_datetime - * RESULT - * const char* value or 0 if value is not valid datetime. - * SEE ALSO - * XMLRPC_SetValueDateTime_IOS8601 () - * XMLRPC_GetValueDateTime () - * XMLRPC_CreateValueDateTime_IOS8601 () - * SOURCE - */ -const char* XMLRPC_GetValueDateTime_ISO8601(XMLRPC_VALUE value) { - return ((value && value->type == xmlrpc_datetime) ? value->str.str : 0); -} - -/*******/ - -/* Get ID (key) of value or NULL */ -/****f* VALUE/XMLRPC_GetValueID - * NAME - * XMLRPC_GetValueID - * SYNOPSIS - * const char* XMLRPC_GetValueID(XMLRPC_VALUE value) - * FUNCTION - * retrieve id (key) of value - * INPUTS - * XMLRPC_VALUE of any type - * RESULT - * const char* pointer to id of value, or NULL - * NOTES - * SEE ALSO - * XMLRPC_SetValueID() - * XMLRPC_CreateValueEmpty() - * SOURCE - */ -const char* XMLRPC_GetValueID(XMLRPC_VALUE value) { - return (const char*)((value && value->id.len) ? value->id.str : 0); -} - -/*******/ - - -/****f* VECTOR/XMLRPC_VectorSize - * NAME - * XMLRPC_VectorSize - * SYNOPSIS - * int XMLRPC_VectorSize(XMLRPC_VALUE value) - * FUNCTION - * retrieve size of vector - * INPUTS - * XMLRPC_VALUE of type xmlrpc_vector - * RESULT - * count of items in vector - * NOTES - * This is a cheap operation even on large vectors. Vector size is - * maintained by queue during add/remove ops. - * SEE ALSO - * XMLRPC_AddValueToVector () - * SOURCE - */ -int XMLRPC_VectorSize(XMLRPC_VALUE value) { - int size = 0; - if(value && value->type == xmlrpc_vector && value->v) { - size = Q_Size(value->v->q); - } - return size; -} - -/*******/ - -/****f* VECTOR/XMLRPC_VectorRewind - * NAME - * XMLRPC_VectorRewind - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value) - * FUNCTION - * reset vector to first item - * INPUTS - * XMLRPC_VALUE of type xmlrpc_vector - * RESULT - * first XMLRPC_VALUE in list, or NULL if empty or error. - * NOTES - * Be careful to rewind any vector passed in to you if you expect to - * iterate through the entire list. - * SEE ALSO - * XMLRPC_VectorNext () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value) { - XMLRPC_VALUE xReturn = NULL; - if(value && value->type == xmlrpc_vector && value->v) { - xReturn = (XMLRPC_VALUE)Q_Head(value->v->q); - } - return xReturn; -} - -/*******/ - -/****f* VECTOR/XMLRPC_VectorNext - * NAME - * XMLRPC_VectorNext - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value) - * FUNCTION - * Iterate vector to next item in list. - * INPUTS - * XMLRPC_VALUE of type xmlrpc_vector - * RESULT - * Next XMLRPC_VALUE in vector, or NULL if at end. - * NOTES - * SEE ALSO - * XMLRPC_VectorRewind () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value) { - XMLRPC_VALUE xReturn = NULL; - if(value && value->type == xmlrpc_vector && value->v) { - xReturn = (XMLRPC_VALUE)Q_Next(value->v->q); - } - return xReturn; -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueType - * NAME - * XMLRPC_GetValueType - * SYNOPSIS - * XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value) - * FUNCTION - * determine data type of the XMLRPC_VALUE - * INPUTS - * XMLRPC_VALUE target of query - * RESULT - * data type of value as enumerated by XMLRPC_VALUE_TYPE - * NOTES - * all values are of type xmlrpc_empty until set. - * Deprecated for public use. See XMLRPC_GetValueTypeEasy - * SEE ALSO - * XMLRPC_SetValue* - * XMLRPC_CreateValue* - * XMLRPC_Append* - * XMLRPC_GetValueTypeEasy () - * SOURCE - */ -XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE value) { - return value ? value->type : xmlrpc_empty; -} - -/*******/ - -/* Vector type accessor */ -/****f* VALUE/XMLRPC_GetVectorType - * NAME - * XMLRPC_GetVectorType - * SYNOPSIS - * XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value) - * FUNCTION - * determine vector type of the XMLRPC_VALUE - * INPUTS - * XMLRPC_VALUE of type xmlrpc_vector - * RESULT - * vector type of value as enumerated by XMLRPC_VECTOR_TYPE. - * xmlrpc_none if not a value. - * NOTES - * xmlrpc_none is returned if value is not a vector - * Deprecated for public use. See XMLRPC_GetValueTypeEasy - * SEE ALSO - * XMLRPC_SetIsVector () - * XMLRPC_GetValueType () - * XMLRPC_GetValueTypeEasy () - * SOURCE - */ -XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE value) { - return(value && value->v) ? value->v->type : xmlrpc_none; -} - -/*******/ - -/****f* VALUE/XMLRPC_GetValueTypeEasy - * NAME - * XMLRPC_GetValueTypeEasy - * SYNOPSIS - * XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy(XMLRPC_VALUE value) - * FUNCTION - * determine data type of the XMLRPC_VALUE. includes vector types. - * INPUTS - * XMLRPC_VALUE target of query - * RESULT - * data type of value as enumerated by XMLRPC_VALUE_TYPE_EASY - * xmlrpc_type_none if not a value. - * NOTES - * all values are of type xmlrpc_type_empty until set. - * SEE ALSO - * XMLRPC_SetValue* - * XMLRPC_CreateValue* - * XMLRPC_Append* - * SOURCE - */ -XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy (XMLRPC_VALUE value) { - if (value) { - switch (value->type) { - case xmlrpc_vector: - switch (value->v->type) { - case xmlrpc_vector_none: - return xmlrpc_type_none; - case xmlrpc_vector_struct: - return xmlrpc_type_struct; - case xmlrpc_vector_mixed: - return xmlrpc_type_mixed; - case xmlrpc_vector_array: - return xmlrpc_type_array; - } - default: - /* evil cast, but we know they are the same */ - return(XMLRPC_VALUE_TYPE_EASY) value->type; - } - } - return xmlrpc_none; -} - -/*******/ - - - -/*-******************* -* Begin Server Funcs * -*********************/ - - -/****f* VALUE/XMLRPC_ServerCreate - * NAME - * XMLRPC_ServerCreate - * SYNOPSIS - * XMLRPC_SERVER XMLRPC_ServerCreate() - * FUNCTION - * Allocate/Init XMLRPC Server Resources. - * INPUTS - * none - * RESULT - * newly allocated XMLRPC_SERVER - * NOTES - * SEE ALSO - * XMLRPC_ServerDestroy () - * XMLRPC_GetGlobalServer () - * SOURCE - */ -XMLRPC_SERVER XMLRPC_ServerCreate() { - XMLRPC_SERVER server = calloc(1, sizeof(STRUCT_XMLRPC_SERVER)); - if(server) { - Q_Init(&server->methodlist); - Q_Init(&server->docslist); - - /* register system methods */ - xsm_register(server); - } - return server; -} - -/*******/ - -/* Return global server. Not locking! Not Thread Safe! */ -/****f* VALUE/XMLRPC_GetGlobalServer - * NAME - * XMLRPC_GetGlobalServer - * SYNOPSIS - * XMLRPC_SERVER XMLRPC_GetGlobalServer() - * FUNCTION - * Allocates a global (process-wide) server, or returns pointer if pre-existing. - * INPUTS - * none - * RESULT - * pointer to global server, or 0 if error. - * NOTES - * ***WARNING*** This function is not thread safe. It is included only for the very lazy. - * Multi-threaded programs that use this may experience problems. - * BUGS - * There is currently no way to cleanup the global server gracefully. - * SEE ALSO - * XMLRPC_ServerCreate () - * SOURCE - */ -XMLRPC_SERVER XMLRPC_GetGlobalServer() { - static XMLRPC_SERVER xsServer = 0; - if(!xsServer) { - xsServer = XMLRPC_ServerCreate(); - } - return xsServer; -} - -/*******/ - -/****f* VALUE/XMLRPC_ServerDestroy - * NAME - * XMLRPC_ServerDestroy - * SYNOPSIS - * void XMLRPC_ServerDestroy(XMLRPC_SERVER server) - * FUNCTION - * Free Server Resources - * INPUTS - * server The server to be free'd - * RESULT - * void - * NOTES - * This frees the server struct and any methods that have been added. - * SEE ALSO - * XMLRPC_ServerCreate () - * SOURCE - */ -void XMLRPC_ServerDestroy(XMLRPC_SERVER server) { - if(server) { - doc_method* dm = Q_Head(&server->docslist); - server_method* sm = Q_Head(&server->methodlist); - while( dm ) { - my_free(dm); - dm = Q_Next(&server->docslist); - } - while( sm ) { - if(sm->name) { - my_free(sm->name); - } - if(sm->desc) { - XMLRPC_CleanupValue(sm->desc); - } - my_free(sm); - sm = Q_Next(&server->methodlist); - } - if(server->xIntrospection) { - XMLRPC_CleanupValue(server->xIntrospection); - } - - Q_Destroy(&server->methodlist); - Q_Destroy(&server->docslist); - my_free(server); - } -} - -/*******/ - - -/****f* VALUE/XMLRPC_ServerRegisterMethod - * NAME - * XMLRPC_ServerRegisterMethod - * SYNOPSIS - * void XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) - * FUNCTION - * Register new XMLRPC method with server - * INPUTS - * server The XMLRPC_SERVER to register the method with - * name public name of the method - * cb C function that implements the method - * RESULT - * int - 1 if success, else 0 - * NOTES - * A C function must be registered for every "method" that the server recognizes. The - * method name is equivalent to method name in the - * XML syntax. - * SEE ALSO - * XMLRPC_ServerFindMethod () - * XMLRPC_ServerCallMethod () - * SOURCE - */ -int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb) { - if(server && name && cb) { - - server_method* sm = malloc(sizeof(server_method)); - - if(sm) { - sm->name = strdup(name); - sm->method = cb; - sm->desc = NULL; - - return Q_PushTail(&server->methodlist, sm); - } - } - return 0; -} - -/*******/ - -server_method* find_method(XMLRPC_SERVER server, const char* name) { - server_method* sm; - - q_iter qi = Q_Iter_Head_F(&server->methodlist); - - while( qi ) { - sm = Q_Iter_Get_F(qi); - if(sm && !strcmp(sm->name, name)) { - return sm; - } - qi = Q_Iter_Next_F(qi); - } - return NULL; -} - - -const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype) { - switch(type) { - case xmlrpc_none: - return "none"; - case xmlrpc_empty: - return "empty"; - case xmlrpc_nil: - return "nil"; - case xmlrpc_base64: - return "base64"; - case xmlrpc_boolean: - return "boolean"; - case xmlrpc_datetime: - return "datetime"; - case xmlrpc_double: - return "double"; - case xmlrpc_int: - return "int"; - case xmlrpc_string: - return "string"; - case xmlrpc_vector: - switch(vtype) { - case xmlrpc_vector_none: - return "none"; - case xmlrpc_vector_array: - return "array"; - case xmlrpc_vector_mixed: - return "mixed vector (struct)"; - case xmlrpc_vector_struct: - return "struct"; - } - } - return "unknown"; -} - -/****f* VALUE/XMLRPC_ServerFindMethod - * NAME - * XMLRPC_ServerFindMethod - * SYNOPSIS - * XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName) - * FUNCTION - * retrieve C callback associated with a given method name. - * INPUTS - * server The XMLRPC_SERVER the method is registered with - * callName the method to find - * RESULT - * previously registered XMLRPC_Callback, or NULL - * NOTES - * Typically, this is used to determine if a requested method exists, without actually calling it. - * SEE ALSO - * XMLRPC_ServerCallMethod () - * XMLRPC_ServerRegisterMethod () - * SOURCE - */ -XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName) { - if(server && callName) { - q_iter qi = Q_Iter_Head_F(&server->methodlist); - while( qi ) { - server_method* sm = Q_Iter_Get_F(qi); - if(sm && !strcmp(sm->name, callName)) { - return sm->method; - } - qi = Q_Iter_Next_F(qi); - } - } - return NULL; -} - -/*******/ - - -/* Call method specified in request */ -/****f* VALUE/XMLRPC_ServerCallMethod - * NAME - * XMLRPC_ServerCallMethod - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) - * FUNCTION - * - * INPUTS - * server The XMLRPC_SERVER the method is registered with - * request the request to handle - * userData any additional data to pass to the C callback, or NULL - * RESULT - * XMLRPC_VALUE allocated by the callback, or NULL - * NOTES - * It is typically the caller's responsibility to free the returned value. - * - * Often the caller will want to serialize the result as XML, via - * XMLRPC_VALUE_To_XML () or XMLRPC_REQUEST_To_XML () - * SEE ALSO - * XMLRPC_ServerFindMethod () - * XMLRPC_ServerRegisterMethod () - * XMLRPC_CleanupValue () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData) { - XMLRPC_VALUE xReturn = NULL; - - /* check for error set during request parsing / generation */ - if(request && request->error) { - xReturn = XMLRPC_CopyValue(request->error); - } - else if (server && request) { - XMLRPC_Callback cb = - XMLRPC_ServerFindMethod (server, request->methodName.str); - if(cb) { - xReturn = cb(server, request, userData); - } - else { - xReturn = - XMLRPC_UtilityCreateFault (xmlrpc_error_unknown_method, - request->methodName.str); - } - } - return xReturn; -} - -/*******/ - -/*-***************** -* End server funcs * -*******************/ - - -/*-*********************************** -* Begin XMLRPC General Options funcs * -*************************************/ - -/* For options used by XMLRPC_VALUE funcs that otherwise do not have - * parameters for options. Kind of gross. :( - */ -typedef struct _xmlrpc_options { - XMLRPC_CASE id_case; - XMLRPC_CASE_COMPARISON id_case_compare; -} -STRUCT_XMLRPC_OPTIONS, *XMLRPC_OPTIONS; - -static XMLRPC_OPTIONS XMLRPC_GetDefaultOptions() { - static STRUCT_XMLRPC_OPTIONS options = { - xmlrpc_case_exact, - xmlrpc_case_sensitive - }; - return &options; -} - -/****f* VALUE/XMLRPC_GetDefaultIdCase - * NAME - * XMLRPC_GetDefaultIdCase - * SYNOPSIS - * XMLRPC_CASE XMLRPC_GetDefaultIdCase() - * FUNCTION - * Gets default case options used by XMLRPC_VALUE funcs - * INPUTS - * none - * RESULT - * XMLRPC_CASE - * BUGS - * Nasty and gross. Should be server specific, but that requires changing all - * the XMLRPC_VALUE api's. - * SEE ALSO - * XMLRPC_SetDefaultIdCase () - * SOURCE - */ -XMLRPC_CASE XMLRPC_GetDefaultIdCase() { - XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions(); - return options->id_case; -} - -/*******/ - -/****f* VALUE/XMLRPC_SetDefaultIdCase - * NAME - * XMLRPC_SetDefaultIdCase - * SYNOPSIS - * XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case) - * FUNCTION - * Sets default case options used by XMLRPC_VALUE funcs - * INPUTS - * id_case case options as enumerated by XMLRPC_CASE - * RESULT - * XMLRPC_CASE -- newly set option - * BUGS - * Nasty and gross. Should be server specific, but that requires changing all - * the XMLRPC_VALUE api's. - * SEE ALSO - * XMLRPC_GetDefaultIdCase () - * SOURCE - */ -XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case) { - XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions(); - options->id_case = id_case; - return options->id_case; -} - -/*******/ - -/****f* VALUE/XMLRPC_GetDefaultIdCaseComparison - * NAME - * XMLRPC_GetDefaultIdCaseComparison - * SYNOPSIS - * XMLRPC_CASE XMLRPC_GetDefaultIdCaseComparison( ) - * FUNCTION - * Gets default case comparison options used by XMLRPC_VALUE funcs - * INPUTS - * none - * RESULT - * XMLRPC_CASE_COMPARISON default - * BUGS - * Nasty and gross. Should be server specific, but that requires changing all - * the XMLRPC_VALUE api's. - * SEE ALSO - * XMLRPC_SetDefaultIdCaseComparison () - * SOURCE - */ -XMLRPC_CASE_COMPARISON XMLRPC_GetDefaultIdCaseComparison() { - XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions(); - return options->id_case_compare; -} - -/*******/ - -/****f* VALUE/XMLRPC_SetDefaultIdCaseComparison - * NAME - * XMLRPC_SetDefaultIdCaseComparison - * SYNOPSIS - * XMLRPC_CASE XMLRPC_SetDefaultIdCaseComparison( XMLRPC_CASE_COMPARISON id_case_compare ) - * FUNCTION - * Gets default case comparison options used by XMLRPC_VALUE funcs - * INPUTS - * id_case_compare case comparison rule to set as default - * RESULT - * XMLRPC_CASE_COMPARISON newly set default - * BUGS - * Nasty and gross. Should be server specific, but that requires changing all - * the XMLRPC_VALUE api's. - * SEE ALSO - * XMLRPC_GetDefaultIdCaseComparison () - * SOURCE - */ -XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON id_case_compare) { - XMLRPC_OPTIONS options = XMLRPC_GetDefaultOptions(); - options->id_case_compare = id_case_compare; - return options->id_case_compare; -} - -/*******/ - -/*-********************************* -* End XMLRPC General Options funcs * -***********************************/ - - -/*-****************** -* Fault API funcs * -********************/ - -/****f* UTILITY/XMLRPC_UtilityCreateFault - * NAME - * XMLRPC_UtilityCreateFault - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_UtilityCreateFault( int fault_code, const char* fault_string ) - * FUNCTION - * generates a struct containing a string member with id "faultString" and an int member - * with id "faultCode". When using the xmlrpc xml serialization, these will be translated - * to ... format. - * INPUTS - * fault_code application specific error code. can be 0. - * fault_string application specific error string. cannot be null. - * RESULT - * XMLRPC_VALUE a newly created struct vector representing the error, or null on error. - * NOTES - * This is a utility function. xmlrpc "faults" are not directly represented in this xmlrpc - * API or data structures. It is the author's view, that this API is intended for simple - * data types, and a "fault" is a complex data type consisting of multiple simple data - * types. This function is provided for convenience only, the same result could be - * achieved directly by the application. - * - * This function now supports some "standardized" fault codes, as specified at. - * http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php. - * If one of these fault codes is received, the description string will automatically - * be prefixed with a standard error string and 2 newlines. - * - * The actual transformation between this complex type and the xml "" element takes - * place in the xmlrpc to xml serialization layer. This step is not performed when using the - * simplerpc serialization, meaning that there will be no "" element in that - * serialization. There will simply be a standard struct with 2 child elements. - * imho, the "" element is unnecessary and/or out of place as part of the standard API. - * - * SOURCE - */ -XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string) { - XMLRPC_VALUE xOutput = NULL; - - char* string = NULL; - simplestring description; - simplestring_init(&description); - - switch (fault_code) { - case xmlrpc_error_parse_xml_syntax: - string = xmlrpc_error_parse_xml_syntax_str; - break; - case xmlrpc_error_parse_unknown_encoding: - string = xmlrpc_error_parse_unknown_encoding_str; - break; - case xmlrpc_error_parse_bad_encoding: - string = xmlrpc_error_parse_bad_encoding_str; - break; - case xmlrpc_error_invalid_xmlrpc: - string = xmlrpc_error_invalid_xmlrpc_str; - break; - case xmlrpc_error_unknown_method: - string = xmlrpc_error_unknown_method_str; - break; - case xmlrpc_error_invalid_params: - string = xmlrpc_error_invalid_params_str; - break; - case xmlrpc_error_internal_server: - string = xmlrpc_error_internal_server_str; - break; - case xmlrpc_error_application: - string = xmlrpc_error_application_str; - break; - case xmlrpc_error_system: - string = xmlrpc_error_system_str; - break; - case xmlrpc_error_transport: - string = xmlrpc_error_transport_str; - break; - } - - simplestring_add(&description, string); - - if(string && fault_string) { - simplestring_add(&description, "\n\n"); - } - simplestring_add(&description, fault_string); - - - if(description.len) { - xOutput = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); - - XMLRPC_VectorAppendString (xOutput, "faultString", description.str, - description.len); - XMLRPC_VectorAppendInt(xOutput, "faultCode", fault_code); - } - - simplestring_free(&description); - - return xOutput; -} - -/*******/ - - -/****f* FAULT/XMLRPC_ValueIsFault - * NAME - * XMLRPC_ValueIsFault - * SYNOPSIS - * int XMLRPC_ValueIsFault (XMLRPC_VALUE value) - * FUNCTION - * Determines if a value encapsulates a fault "object" - * INPUTS - * value any XMLRPC_VALUE - * RESULT - * 1 if it is a fault, else 0 - * SEE ALSO - * XMLRPC_ResponseIsFault () - * SOURCE - */ -int XMLRPC_ValueIsFault (XMLRPC_VALUE value) { - if( XMLRPC_VectorGetValueWithID(value, "faultCode") && - XMLRPC_VectorGetValueWithID(value, "faultString") ) { - return 1; - } - return 0; -} -/*******/ - - -/****f* FAULT/XMLRPC_ResponseIsFault - * NAME - * XMLRPC_ResponseIsFault - * SYNOPSIS - * int XMLRPC_ResponseIsFault (XMLRPC_REQUEST response) - * FUNCTION - * Determines if a response contains an encapsulated fault "object" - * INPUTS - * value any XMLRPC_REQUEST. typically of type xmlrpc_request_response - * RESULT - * 1 if it contains a fault, else 0 - * SEE ALSO - * XMLRPC_ValueIsFault () - * SOURCE - */ -int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response) { - return XMLRPC_ValueIsFault( XMLRPC_RequestGetData(response) ); -} - -/*******/ - -/****f* FAULT/XMLRPC_GetValueFaultCode - * NAME - * XMLRPC_GetValueFaultCode - * SYNOPSIS - * int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value) - * FUNCTION - * returns fault code from a struct, if any - * INPUTS - * value XMLRPC_VALUE of type xmlrpc_vector_struct. - * RESULT - * fault code, else 0. - * BUGS - * impossible to distinguish faultCode == 0 from faultCode not present. - * SEE ALSO - * XMLRPC_GetResponseFaultCode () - * SOURCE - */ -int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value) { - return XMLRPC_VectorGetIntWithID(value, "faultCode"); -} - -/*******/ - -/****f* FAULT/XMLRPC_GetResponseFaultCode - * NAME - * XMLRPC_GetResponseFaultCode - * SYNOPSIS - * int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response) - * FUNCTION - * returns fault code from a response, if any - * INPUTS - * response XMLRPC_REQUEST. typically of type xmlrpc_request_response. - * RESULT - * fault code, else 0. - * BUGS - * impossible to distinguish faultCode == 0 from faultCode not present. - * SEE ALSO - * XMLRPC_GetValueFaultCode () - * SOURCE - */ -int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response) { - return XMLRPC_GetValueFaultCode( XMLRPC_RequestGetData(response) ); -} - -/*******/ - - -/****f* FAULT/XMLRPC_GetValueFaultString - * NAME - * XMLRPC_GetValueFaultString - * SYNOPSIS - * const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value) - * FUNCTION - * returns fault string from a struct, if any - * INPUTS - * value XMLRPC_VALUE of type xmlrpc_vector_struct. - * RESULT - * fault string, else 0. - * SEE ALSO - * XMLRPC_GetResponseFaultString () - * SOURCE - */ -const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value) { - return XMLRPC_VectorGetStringWithID(value, "faultString"); -} - -/*******/ - -/****f* FAULT/XMLRPC_GetResponseFaultString - * NAME - * XMLRPC_GetResponseFaultString - * SYNOPSIS - * const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response) - * FUNCTION - * returns fault string from a response, if any - * INPUTS - * response XMLRPC_REQUEST. typically of type xmlrpc_request_response. - * RESULT - * fault string, else 0. - * SEE ALSO - * XMLRPC_GetValueFaultString () - * SOURCE - */ -const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response) { - return XMLRPC_GetValueFaultString( XMLRPC_RequestGetData(response) ); -} - -/*******/ - - -/*-****************** -* Utility API funcs * -********************/ - - -/****f* UTILITY/XMLRPC_Free - * NAME - * XMLRPC_Free - * SYNOPSIS - * void XMLRPC_Free(void* mem) - * FUNCTION - * frees a block of memory allocated by xmlrpc. - * INPUTS - * mem memory to free - * RESULT - * void - * NOTES - * Useful for OS's where memory must be free'd - * in the same library in which it is allocated. - * SOURCE - */ -void XMLRPC_Free(void* mem) { - my_free(mem); -} - -/*******/ - - -/****f* UTILITY/XMLRPC_GetVersionString - * NAME - * XMLRPC_GetVersionString - * SYNOPSIS - * const char* XMLRPC_GetVersionString() - * FUNCTION - * returns library version string - * INPUTS - * - * RESULT - * const char* - * NOTES - * SOURCE - */ -const char* XMLRPC_GetVersionString() { - return XMLRPC_VERSION_STR; -} - -/*******/ - - -/*-********************** -* End Utility API funcs * -************************/ diff --git a/php/xmlrpc/libxmlrpc/xmlrpc.h b/php/xmlrpc/libxmlrpc/xmlrpc.h deleted file mode 100644 index eead11c..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -#ifndef XMLRPC_ALREADY_INCLUDED -#define XMLRPC_ALREADY_INCLUDED 1 - -/* includes */ -#include "xml_element.h" -#include /* for time_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* allow version to be specified via compile line define */ -#ifndef XMLRPC_LIB_VERSION - #define XMLRPC_LIB_VERSION "0.51" -#endif - -/* this number, representing the date, must be increased each time the API changes */ -#define XMLRPC_API_NO 20020623 - -/* this string should be changed with each packaged release */ -#define XMLRPC_VERSION_STR "xmlrpc-epi v. " XMLRPC_LIB_VERSION - -/* where to find more info. shouldn't need to change much */ -#define XMLRPC_HOME_PAGE_STR "http://xmlprc-epi.sourceforge.net/" - - -/****d* VALUE/XMLRPC_VALUE_TYPE - * NAME - * XMLRPC_VALUE_TYPE - * NOTES - * Defines data types for XMLRPC_VALUE - * Deprecated for public use. See XMLRPC_VALUE_TYPE_EASY - * SEE ALSO - * XMLRPC_VECTOR_TYPE - * XMLRPC_REQUEST_TYPE - * SOURCE - */ -typedef enum _XMLRPC_VALUE_TYPE { - xmlrpc_none, /* not a value */ - xmlrpc_empty, /* empty value */ - xmlrpc_nil, /* null value, eg NULL */ - xmlrpc_base64, /* base64 value, eg binary data */ - xmlrpc_boolean, /* boolean [0 | 1] */ - xmlrpc_datetime, /* datetime [ISO8601 | time_t] */ - xmlrpc_double, /* double / floating point */ - xmlrpc_int, /* integer */ - xmlrpc_string, /* string */ - xmlrpc_vector /* vector, aka list, array */ -} XMLRPC_VALUE_TYPE; -/*******/ - -/****d* VALUE/XMLRPC_VECTOR_TYPE - * NAME - * XMLRPC_VECTOR_TYPE - * NOTES - * Defines data types for XMLRPC_VECTOR. - * Deprecated for public use. See XMLRPC_VALUE_TYPE_EASY - * SEE ALSO - * XMLRPC_VALUE_TYPE - * XMLRPC_REQUEST_TYPE - * SOURCE - */ -typedef enum _XMLRPC_VECTOR_TYPE { - xmlrpc_vector_none, /* not an array */ - xmlrpc_vector_array, /* no values may have key names */ - xmlrpc_vector_mixed, /* some values may have key names */ - xmlrpc_vector_struct /* all values must have key names */ -} XMLRPC_VECTOR_TYPE; -/*******/ - -/****d* VALUE/XMLRPC_VALUE_TYPE_EASY - * NAME - * XMLRPC_VALUE_TYPE_EASY - * NOTES - * Defines data types for XMLRPC_VALUE, including vector types. - * SEE ALSO - * XMLRPC_VECTOR_TYPE - * XMLRPC_REQUEST_TYPE - * SOURCE - */ -typedef enum _XMLRPC_VALUE_TYPE_EASY { - xmlrpc_type_none, /* not a value */ - xmlrpc_type_empty, /* empty value, eg NULL */ - xmlrpc_type_base64, /* base64 value, eg binary data */ - xmlrpc_type_boolean, /* boolean [0 | 1] */ - xmlrpc_type_datetime, /* datetime [ISO8601 | time_t] */ - xmlrpc_type_double, /* double / floating point */ - xmlrpc_type_int, /* integer */ - xmlrpc_type_string, /* string */ -/* -- IMPORTANT: identical to XMLRPC_VALUE_TYPE to this point. -- */ - xmlrpc_type_array, /* vector array */ - xmlrpc_type_mixed, /* vector mixed */ - xmlrpc_type_struct /* vector struct */ -} XMLRPC_VALUE_TYPE_EASY; -/*******/ - - -/****d* VALUE/XMLRPC_REQUEST_TYPE - * NAME - * XMLRPC_REQUEST_TYPE - * NOTES - * Defines data types for XMLRPC_REQUEST - * SEE ALSO - * XMLRPC_VALUE_TYPE - * XMLRPC_VECTOR_TYPE - * SOURCE - */ -typedef enum _xmlrpc_request_type { - xmlrpc_request_none, /* not a valid request */ - xmlrpc_request_call, /* calling/invoking a method */ - xmlrpc_request_response, /* responding to a method call */ -} XMLRPC_REQUEST_TYPE; -/*******/ - -/****d* VALUE/XMLRPC_ERROR_CODE - * NAME - * XMLRPC_ERROR_CODE - * NOTES - * All existing error codes - * SEE ALSO - * XMLRPC_REQUEST_ERROR - * SOURCE - */ -typedef enum _xmlrpc_error_code { - xmlrpc_error_none = 0, /* not an error */ - xmlrpc_error_parse_xml_syntax = -32700, - xmlrpc_error_parse_unknown_encoding = -32701, - xmlrpc_error_parse_bad_encoding = -32702, - xmlrpc_error_invalid_xmlrpc = -32600, - xmlrpc_error_unknown_method = -32601, - xmlrpc_error_invalid_params = -32602, - xmlrpc_error_internal_server = -32603, - xmlrpc_error_application = -32500, - xmlrpc_error_system = -32400, - xmlrpc_error_transport = -32300 -} XMLRPC_ERROR_CODE; -/******/ - -#define xmlrpc_error_parse_xml_syntax_str "parse error. not well formed." -#define xmlrpc_error_parse_unknown_encoding_str "parse error. unknown encoding" -#define xmlrpc_error_parse_bad_encoding_str "parse error. invalid character for encoding" -#define xmlrpc_error_invalid_xmlrpc_str "server error. xml-rpc not conforming to spec" -#define xmlrpc_error_unknown_method_str "server error. method not found." -#define xmlrpc_error_invalid_params_str "server error. invalid method parameters" -#define xmlrpc_error_internal_server_str "server error. internal xmlrpc library error" -#define xmlrpc_error_application_str "application error." -#define xmlrpc_error_system_str "system error." -#define xmlrpc_error_transport_str "transport error." - - - -/****d* VALUE/XMLRPC_VERSION - * NAME - * XMLRPC_VERSION - * NOTES - * Defines xml vocabulary used for generated xml - * SEE ALSO - * XMLRPC_REQUEST_OUTPUT_OPTIONS - * XMLRPC_REQUEST_To_XML () - * SOURCE - */ -typedef enum _xmlrpc_version { - xmlrpc_version_none = 0, /* not a recognized vocabulary */ - xmlrpc_version_1_0 = 1, /* xmlrpc 1.0 standard vocab */ - xmlrpc_version_simple = 2, /* alt more readable vocab */ - xmlrpc_version_danda = 2, /* same as simple. legacy */ - xmlrpc_version_soap_1_1 = 3 /* SOAP. version 1.1 */ -} XMLRPC_VERSION; -/******/ - -/****s* VALUE/XMLRPC_REQUEST_OUTPUT_OPTIONS - * NAME - * XMLRPC_REQUEST_OUTPUT_OPTIONS - * NOTES - * Defines output options for generated xml - * SEE ALSO - * XMLRPC_VERSION - * XML_ELEM_OUTPUT_OPTIONS - * XMLRPC_REQUEST_To_XML () - * SOURCE - */ -typedef struct _xmlrpc_request_output_options { - STRUCT_XML_ELEM_OUTPUT_OPTIONS xml_elem_opts; /* xml_element specific output options */ - XMLRPC_VERSION version; /* xml vocabulary to use */ -} STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS, *XMLRPC_REQUEST_OUTPUT_OPTIONS; -/******/ - -/****s* VALUE/XMLRPC_REQUEST_INPUT_OPTIONS - * NAME - * XMLRPC_REQUEST_INPUT_OPTIONS - * NOTES - * Defines options for reading in xml data - * SEE ALSO - * XMLRPC_VERSION - * XML_ELEM_INPUT_OPTIONS - * XMLRPC_REQUEST_From_XML () - * SOURCE - */ -typedef struct _xmlrpc_request_input_options { - STRUCT_XML_ELEM_INPUT_OPTIONS xml_elem_opts; /* xml_element specific output options */ -} STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS, *XMLRPC_REQUEST_INPUT_OPTIONS; -/******/ - -/****s* VALUE/XMLRPC_ERROR - * NAME - * XMLRPC_ERROR - * NOTES - * For the reporting and handling of errors - * SOURCE - */ -typedef struct _xmlrpc_error { - XMLRPC_ERROR_CODE code; - STRUCT_XML_ELEM_ERROR xml_elem_error; /* xml_element errors (parser errors) */ -} STRUCT_XMLRPC_ERROR, *XMLRPC_ERROR; -/******/ - - -/****d* VALUE/XMLRPC_CASE_COMPARISON - * NAME - * XMLRPC_CASE_COMPARISON - * NOTES - * Defines case comparison options for XMLRPC_VALUE/VECTOR API's - * SEE ALSO - * XMLRPC_CASE - * XMLRPC_VALUE - * SOURCE - */ -typedef enum _xmlrpc_case_comparison { - xmlrpc_case_insensitive, /* use case-insensitive compare */ - xmlrpc_case_sensitive /* use case-sensitive compare */ -} XMLRPC_CASE_COMPARISON; -/******/ - -/****d* VALUE/XMLRPC_CASE - * NAME - * XMLRPC_CASE - * NOTES - * Defines case behavior when setting IDs in XMLRPC_VALUE API's - * SEE ALSO - * XMLRPC_CASE_COMPARISON - * XMLRPC_VALUE - * SOURCE - */ -typedef enum _xmlrpc_case { - xmlrpc_case_exact, /* leave case alone */ - xmlrpc_case_lower, /* lower-case id */ - xmlrpc_case_upper /* upper-case id */ -} XMLRPC_CASE; -/******/ - -/* if you don't like these defaults, you can set them with XMLRPC_SetDefaultIdCase*() */ -#define XMLRPC_DEFAULT_ID_CASE XMLRPC_GetDefaultIdCase() -#define XMLRPC_DEFAULT_ID_CASE_SENSITIVITY XMLRPC_GetDefaultIdCaseComparison() - -/* opaque (non-public) types. defined locally in xmlrpc.c */ -typedef struct _xmlrpc_request* XMLRPC_REQUEST; -typedef struct _xmlrpc_server* XMLRPC_SERVER; -typedef struct _xmlrpc_value* XMLRPC_VALUE; - -/****d* VALUE/XMLRPC_Callback - * NAME - * XMLRPC_Callback - * NOTES - * Function prototype for user defined method handlers (callbacks). - * SEE ALSO - * XMLRPC_ServerRegisterMethod () - * XMLRPC_ServerCallMethod () - * XMLRPC_REQUEST - * XMLRPC_VALUE - * SOURCE - */ -typedef XMLRPC_VALUE (*XMLRPC_Callback)(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); -/******/ - -/* ID Case Defaults */ -XMLRPC_CASE XMLRPC_GetDefaultIdCase(void); -XMLRPC_CASE XMLRPC_SetDefaultIdCase(XMLRPC_CASE id_case); -XMLRPC_CASE_COMPARISON XMLRPC_GetDefaultIdCaseComparison(void); -XMLRPC_CASE_COMPARISON XMLRPC_SetDefaultIdCaseComparison(XMLRPC_CASE_COMPARISON id_case); - -/* Vector manipulation */ -int XMLRPC_VectorSize(XMLRPC_VALUE value); -XMLRPC_VALUE XMLRPC_VectorRewind(XMLRPC_VALUE value); -XMLRPC_VALUE XMLRPC_VectorNext(XMLRPC_VALUE value); -int XMLRPC_SetIsVector(XMLRPC_VALUE value, XMLRPC_VECTOR_TYPE type); -int XMLRPC_AddValueToVector(XMLRPC_VALUE target, XMLRPC_VALUE source); -int XMLRPC_AddValuesToVector(XMLRPC_VALUE target, ...); -int XMLRPC_VectorRemoveValue(XMLRPC_VALUE vector, XMLRPC_VALUE value); -XMLRPC_VALUE XMLRPC_VectorGetValueWithID_Case(XMLRPC_VALUE vector, const char* id, XMLRPC_CASE_COMPARISON id_case); - - -/* Create values */ -XMLRPC_VALUE XMLRPC_CreateValueBoolean(const char* id, int truth); -XMLRPC_VALUE XMLRPC_CreateValueBase64(const char* id, const char* s, int len); -XMLRPC_VALUE XMLRPC_CreateValueDateTime(const char* id, time_t time); -XMLRPC_VALUE XMLRPC_CreateValueDateTime_ISO8601(const char* id, const char *s); -XMLRPC_VALUE XMLRPC_CreateValueDouble(const char* id, double f); -XMLRPC_VALUE XMLRPC_CreateValueInt(const char* id, int i); -XMLRPC_VALUE XMLRPC_CreateValueString(const char* id, const char* s, int len); -XMLRPC_VALUE XMLRPC_CreateValueEmpty(void); -XMLRPC_VALUE XMLRPC_CreateVector(const char* id, XMLRPC_VECTOR_TYPE type); - -/* Cleanup values */ -void XMLRPC_CleanupValue(XMLRPC_VALUE value); - -/* Request error */ -XMLRPC_VALUE XMLRPC_RequestSetError (XMLRPC_REQUEST request, XMLRPC_VALUE error); -XMLRPC_VALUE XMLRPC_RequestGetError (XMLRPC_REQUEST request); - -/* Copy values */ -XMLRPC_VALUE XMLRPC_CopyValue(XMLRPC_VALUE value); -XMLRPC_VALUE XMLRPC_DupValueNew(XMLRPC_VALUE xSource); - -/* Set Values */ -void XMLRPC_SetValueDateTime(XMLRPC_VALUE value, time_t time); -void XMLRPC_SetValueDateTime_ISO8601(XMLRPC_VALUE value, const char* s); -void XMLRPC_SetValueDouble(XMLRPC_VALUE value, double val); -void XMLRPC_SetValueInt(XMLRPC_VALUE value, int val); -void XMLRPC_SetValueBoolean(XMLRPC_VALUE value, int val); -const char *XMLRPC_SetValueString(XMLRPC_VALUE value, const char* s, int len); -void XMLRPC_SetValueBase64(XMLRPC_VALUE value, const char* s, int len); -const char *XMLRPC_SetValueID_Case(XMLRPC_VALUE value, const char* id, int len, XMLRPC_CASE id_case); -#define XMLRPC_SetValueID(value, id, len) XMLRPC_SetValueID_Case(value, id, len, XMLRPC_DEFAULT_ID_CASE) - -/* Get Values */ -const char* XMLRPC_GetValueString(XMLRPC_VALUE value); -int XMLRPC_GetValueStringLen(XMLRPC_VALUE value); -int XMLRPC_GetValueInt(XMLRPC_VALUE value); -int XMLRPC_GetValueBoolean(XMLRPC_VALUE value); -double XMLRPC_GetValueDouble(XMLRPC_VALUE value); -const char* XMLRPC_GetValueBase64(XMLRPC_VALUE value); -time_t XMLRPC_GetValueDateTime(XMLRPC_VALUE value); -const char* XMLRPC_GetValueDateTime_ISO8601(XMLRPC_VALUE value); -const char* XMLRPC_GetValueID(XMLRPC_VALUE value); - -/* Type introspection */ -XMLRPC_VALUE_TYPE XMLRPC_GetValueType(XMLRPC_VALUE v); -XMLRPC_VALUE_TYPE_EASY XMLRPC_GetValueTypeEasy(XMLRPC_VALUE v); -XMLRPC_VECTOR_TYPE XMLRPC_GetVectorType(XMLRPC_VALUE v); - -/* Parsing and Creating XML */ -XMLRPC_REQUEST XMLRPC_REQUEST_FromXML(const char* in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options); -XMLRPC_VALUE XMLRPC_VALUE_FromXML(const char* in_buf, int len, XMLRPC_REQUEST_INPUT_OPTIONS in_options); -char* XMLRPC_REQUEST_ToXML(XMLRPC_REQUEST request, int *buf_len); -char* XMLRPC_VALUE_ToXML(XMLRPC_VALUE val, int* buf_len); - -/* Request manipulation funcs */ -const char* XMLRPC_RequestSetMethodName(XMLRPC_REQUEST request, const char* methodName); -const char* XMLRPC_RequestGetMethodName(XMLRPC_REQUEST request); -XMLRPC_REQUEST XMLRPC_RequestNew(void); -void XMLRPC_RequestFree(XMLRPC_REQUEST request, int bFreeIO); -XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestSetOutputOptions(XMLRPC_REQUEST request, XMLRPC_REQUEST_OUTPUT_OPTIONS output); -XMLRPC_REQUEST_OUTPUT_OPTIONS XMLRPC_RequestGetOutputOptions(XMLRPC_REQUEST request); -XMLRPC_VALUE XMLRPC_RequestSetData(XMLRPC_REQUEST request, XMLRPC_VALUE data); -XMLRPC_VALUE XMLRPC_RequestGetData(XMLRPC_REQUEST request); -XMLRPC_REQUEST_TYPE XMLRPC_RequestSetRequestType(XMLRPC_REQUEST request, XMLRPC_REQUEST_TYPE type); -XMLRPC_REQUEST_TYPE XMLRPC_RequestGetRequestType(XMLRPC_REQUEST request); - -/* Server Creation/Destruction; Method Registration and Invocation */ -XMLRPC_SERVER XMLRPC_ServerCreate(void); -XMLRPC_SERVER XMLRPC_GetGlobalServer(void); /* better to use XMLRPC_ServerCreate if you can */ -void XMLRPC_ServerDestroy(XMLRPC_SERVER server); -int XMLRPC_ServerRegisterMethod(XMLRPC_SERVER server, const char *name, XMLRPC_Callback cb); -XMLRPC_Callback XMLRPC_ServerFindMethod(XMLRPC_SERVER server, const char* callName); -XMLRPC_VALUE XMLRPC_ServerCallMethod(XMLRPC_SERVER server, XMLRPC_REQUEST request, void* userData); - -#include "xmlrpc_introspection.h" - -/* Fault interrogation funcs */ -int XMLRPC_ValueIsFault (XMLRPC_VALUE value); -int XMLRPC_ResponseIsFault(XMLRPC_REQUEST response); -int XMLRPC_GetValueFaultCode (XMLRPC_VALUE value); -int XMLRPC_GetResponseFaultCode(XMLRPC_REQUEST response); -const char* XMLRPC_GetValueFaultString (XMLRPC_VALUE value); -const char* XMLRPC_GetResponseFaultString (XMLRPC_REQUEST response); - - -/* Public Utility funcs */ -XMLRPC_VALUE XMLRPC_UtilityCreateFault(int fault_code, const char* fault_string); -void XMLRPC_Free(void* mem); -const char* XMLRPC_GetVersionString(void); - -/****d* VALUE/XMLRPC_MACROS - * NAME - * Some Helpful Macros - * NOTES - * Some macros for making life easier. Should be self-explanatory. - * SEE ALSO - * XMLRPC_AddValueToVector () - * XMLRPC_VectorGetValueWithID_Case () - * XMLRPC_VALUE - * SOURCE - */ - -/* Append values to vector */ -#define XMLRPC_VectorAppendString(vector, id, s, len) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueString(id, s, len)) -#define XMLRPC_VectorAppendBase64(vector, id, s, len) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueBase64(id, s, len)) -#define XMLRPC_VectorAppendDateTime(vector, id, time) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDateTime(id, time)) -#define XMLRPC_VectorAppendDateTime_ISO8601(vector, id, s) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDateTime_ISO8601(id, s)) -#define XMLRPC_VectorAppendDouble(vector, id, f) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueDouble(id, f)) -#define XMLRPC_VectorAppendInt(vector, id, i) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueInt(id, i)) -#define XMLRPC_VectorAppendBoolean(vector, id, i) XMLRPC_AddValueToVector(vector, XMLRPC_CreateValueBoolean(id, i)) - -/* Get named values from vector */ -#define XMLRPC_VectorGetValueWithID(vector, id) XMLRPC_VectorGetValueWithID_Case(vector, id, XMLRPC_DEFAULT_ID_CASE_SENSITIVITY) -#define XMLRPC_VectorGetStringWithID(vector, id) XMLRPC_GetValueString(XMLRPC_VectorGetValueWithID(vector, id)) -#define XMLRPC_VectorGetBase64WithID(vector, id) XMLRPC_GetValueBase64(XMLRPC_VectorGetValueWithID(vector, id)) -#define XMLRPC_VectorGetDateTimeWithID(vector, id) XMLRPC_GetValueDateTime(XMLRPC_VectorGetValueWithID(vector, id)) -#define XMLRPC_VectorGetDoubleWithID(vector, id) XMLRPC_GetValueDouble(XMLRPC_VectorGetValueWithID(vector, id)) -#define XMLRPC_VectorGetIntWithID(vector, id) XMLRPC_GetValueInt(XMLRPC_VectorGetValueWithID(vector, id)) -#define XMLRPC_VectorGetBooleanWithID(vector, id) XMLRPC_GetValueBoolean(XMLRPC_VectorGetValueWithID(vector, id)) - -/******/ - - -#ifdef __cplusplus -} -#endif - -#endif /* not XMLRPC_ALREADY_INCLUDED */ - - - diff --git a/php/xmlrpc/libxmlrpc/xmlrpc.m4 b/php/xmlrpc/libxmlrpc/xmlrpc.m4 deleted file mode 100644 index 87da92d..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc.m4 +++ /dev/null @@ -1,12 +0,0 @@ -AC_DEFUN([XMLRPC_CHECKS],[ - -AC_REQUIRE([AC_PROG_CC]) -AC_REQUIRE([AC_PROG_LN_S]) -AC_REQUIRE([AC_PROG_RANLIB]) - -AC_DEFINE(UNDEF_THREADS_HACK,,[ ]) - -XMLRPC_HEADER_CHECKS -XMLRPC_TYPE_CHECKS -XMLRPC_FUNCTION_CHECKS -]) diff --git a/php/xmlrpc/libxmlrpc/xmlrpc_introspection.c b/php/xmlrpc/libxmlrpc/xmlrpc_introspection.c deleted file mode 100644 index 589ff8e..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc_introspection.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -/****h* ABOUT/xmlrpc_introspection - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * HISTORY - * $Log: xmlrpc_introspection.c,v $ - * Revision 1.4 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.3 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.9 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 4/10/2001 -- danda -- initial introspection support - * TODO - * NOTES - *******/ - - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include "queue.h" -#include "xmlrpc.h" -#include "xmlrpc_private.h" -#include "xmlrpc_introspection_private.h" -#include -#include -#include - - -/* forward declarations for static (non public, non api) funcs */ -static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); -static XMLRPC_VALUE xi_system_list_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); -static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); -static XMLRPC_VALUE xi_system_method_help_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData); - - -/*-********************************** -* Introspection Callbacks (methods) * -************************************/ - -/* iterates through a list of structs and finds the one with key "name" matching - * needle. slow, would benefit from a struct key hash. - */ -inline XMLRPC_VALUE find_named_value(XMLRPC_VALUE list, const char* needle) { - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(list); - while(xIter) { - const char* name = XMLRPC_VectorGetStringWithID(xIter, xi_token_name); - if(name && !strcmp(name, needle)) { - return xIter; - } - xIter = XMLRPC_VectorNext(list); - } - return NULL; -} - - -/* iterates through docs callbacks and calls any that have not yet been called */ -static void check_docs_loaded(XMLRPC_SERVER server, void* userData) { - if(server) { - q_iter qi = Q_Iter_Head_F(&server->docslist); - while( qi ) { - doc_method* dm = Q_Iter_Get_F(qi); - if(dm && !dm->b_called) { - dm->method(server, userData); - dm->b_called = 1; - } - qi = Q_Iter_Next_F(qi); - } - } -} - - -/* utility function for xi_system_describe_methods_cb */ -inline void describe_method(XMLRPC_SERVER server, XMLRPC_VALUE vector, const char* method) { - if(method) { - server_method* sm = find_method(server, method); - if(sm) { - XMLRPC_AddValueToVector(vector, sm->desc); - } - } -} - - - -/* system.describeMethods() callback */ -static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - XMLRPC_VALUE xParams = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); - XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); - XMLRPC_VALUE xMethodList = XMLRPC_CreateVector("methodList", xmlrpc_vector_array); - XMLRPC_VALUE xTypeList = NULL; - int bAll = 1; - - /* lazy loading of introspection data */ - check_docs_loaded(server, userData); - - xTypeList = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); - - XMLRPC_AddValueToVector(xResponse, xTypeList); - XMLRPC_AddValueToVector(xResponse, xMethodList); - - /* check if we have any param */ - if(xParams) { - /* check if string or vector (1 or n) */ - XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(xParams); - if(type == xmlrpc_string) { - /* just one. spit it out. */ - describe_method(server, xMethodList, XMLRPC_GetValueString(xParams)); - bAll = 0; - } - else if(type == xmlrpc_vector) { - /* multiple. spit all out */ - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xParams); - while(xIter) { - describe_method(server, xMethodList, XMLRPC_GetValueString(xIter)); - xIter = XMLRPC_VectorNext(xParams); - } - bAll = 0; - } - } - - /* otherwise, default to sending all methods */ - if(bAll) { - q_iter qi = Q_Iter_Head_F(&server->methodlist); - while( qi ) { - server_method* sm = Q_Iter_Get_F(qi); - if(sm) { - XMLRPC_AddValueToVector(xMethodList, sm->desc); - } - qi = Q_Iter_Next_F(qi); - } - } - - return xResponse; -} - -/* this complies with system.listMethods as defined at http://xmlrpc.usefulinc.com/doc/reserved.html */ -static XMLRPC_VALUE xi_system_list_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); - - q_iter qi = Q_Iter_Head_F(&server->methodlist); - while( qi ) { - server_method* sm = Q_Iter_Get_F(qi); - if(sm) { - XMLRPC_VectorAppendString(xResponse, 0, sm->name, 0); - } - qi = Q_Iter_Next_F(qi); - } - return xResponse; -} - -/* this complies with system.methodSignature as defined at - * http://xmlrpc.usefulinc.com/doc/sysmethodsig.html - */ -static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); - XMLRPC_VALUE xResponse = NULL; - - /* lazy loading of introspection data */ - check_docs_loaded(server, userData); - - if(method) { - server_method* sm = find_method(server, method); - if(sm && sm->desc) { - XMLRPC_VALUE xTypesArray = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); - XMLRPC_VALUE xIter, xParams, xSig, xSigIter; - const char* type; - - /* array of possible signatures. */ - xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); - - /* find first signature */ - xSig = XMLRPC_VectorGetValueWithID(sm->desc, xi_token_signatures); - xSigIter = XMLRPC_VectorRewind( xSig ); - - /* iterate through sigs */ - while(xSigIter) { - /* first type is the return value */ - type = XMLRPC_VectorGetStringWithID(XMLRPC_VectorRewind( - XMLRPC_VectorGetValueWithID(xSigIter, xi_token_returns)), - xi_token_type); - XMLRPC_AddValueToVector(xTypesArray, - XMLRPC_CreateValueString(NULL, - type ? type : type_to_str(xmlrpc_none, 0), - 0)); - - /* the rest are parameters */ - xParams = XMLRPC_VectorGetValueWithID(xSigIter, xi_token_params); - xIter = XMLRPC_VectorRewind(xParams); - - /* iter through params, adding to types array */ - while(xIter) { - XMLRPC_AddValueToVector(xTypesArray, - XMLRPC_CreateValueString(NULL, - XMLRPC_VectorGetStringWithID(xIter, xi_token_type), - 0)); - xIter = XMLRPC_VectorNext(xParams); - } - - /* add types for this signature */ - XMLRPC_AddValueToVector(xResponse, xTypesArray); - - xSigIter = XMLRPC_VectorNext( xSig ); - } - } - } - - return xResponse; -} - -/* this complies with system.methodHelp as defined at - * http://xmlrpc.usefulinc.com/doc/sysmethhelp.html - */ -static XMLRPC_VALUE xi_system_method_help_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { - const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); - XMLRPC_VALUE xResponse = NULL; - - /* lazy loading of introspection data */ - check_docs_loaded(server, userData); - - if(method) { - server_method* sm = find_method(server, method); - if(sm && sm->desc) { - const char* help = XMLRPC_VectorGetStringWithID(sm->desc, xi_token_purpose); - - /* returns a documentation string, or empty string */ - xResponse = XMLRPC_CreateValueString(NULL, help ? help : xi_token_empty, 0); - } - } - - return xResponse; -} - -/*-************************************** -* End Introspection Callbacks (methods) * -****************************************/ - - -/*-************************ -* Introspection Utilities * -**************************/ - -/* performs registration of introspection methods */ -void xi_register_system_methods(XMLRPC_SERVER server) { - XMLRPC_ServerRegisterMethod(server, xi_token_system_list_methods, xi_system_list_methods_cb); - XMLRPC_ServerRegisterMethod(server, xi_token_system_method_help, xi_system_method_help_cb); - XMLRPC_ServerRegisterMethod(server, xi_token_system_method_signature, xi_system_method_signature_cb); - XMLRPC_ServerRegisterMethod(server, xi_token_system_describe_methods, xi_system_describe_methods_cb); -} - -/* describe a value (param, return, type) */ -static XMLRPC_VALUE describeValue_worker(const char* type, const char* id, const char* desc, int optional, const char* default_val, XMLRPC_VALUE sub_params) { - XMLRPC_VALUE xParam = NULL; - if(id || desc) { - xParam = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); - XMLRPC_VectorAppendString(xParam, xi_token_name, id, 0); - XMLRPC_VectorAppendString(xParam, xi_token_type, type, 0); - XMLRPC_VectorAppendString(xParam, xi_token_description, desc, 0); - if(optional != 2) { - XMLRPC_VectorAppendInt(xParam, xi_token_optional, optional); - } - if(optional == 1 && default_val) { - XMLRPC_VectorAppendString(xParam, xi_token_default, default_val, 0); - } - XMLRPC_AddValueToVector(xParam, sub_params); - } - return xParam; -} - - -/* convert an xml tree conforming to spec to XMLRPC_VALUE - * suitable for use with XMLRPC_ServerAddIntrospectionData - */ -XMLRPC_VALUE xml_element_to_method_description(xml_element* el, XMLRPC_ERROR err) { - XMLRPC_VALUE xReturn = NULL; - - if(el->name) { - const char* name = NULL; - const char* type = NULL; - const char* basetype = NULL; - const char* desc = NULL; - const char* def = NULL; - int optional = 0; - xml_element_attr* attr_iter = Q_Head(&el->attrs); - - /* grab element attributes up front to save redundant while loops */ - while(attr_iter) { - if(!strcmp(attr_iter->key, "name")) { - name = attr_iter->val; - } - else if(!strcmp(attr_iter->key, "type")) { - type = attr_iter->val; - } - else if(!strcmp(attr_iter->key, "basetype")) { - basetype = attr_iter->val; - } - else if(!strcmp(attr_iter->key, "desc")) { - desc = attr_iter->val; - } - else if(!strcmp(attr_iter->key, "optional")) { - if(attr_iter->val && !strcmp(attr_iter->val, "yes")) { - optional = 1; - } - } - else if(!strcmp(attr_iter->key, "default")) { - def = attr_iter->val; - } - attr_iter = Q_Next(&el->attrs); - } - - /* value and typeDescription behave about the same */ - if(!strcmp(el->name, "value") || !strcmp(el->name, "typeDescription")) { - XMLRPC_VALUE xSubList = NULL; - const char* ptype = !strcmp(el->name, "value") ? type : basetype; - if(ptype) { - if(Q_Size(&el->children) && - (!strcmp(ptype, "array") || !strcmp(ptype, "struct") || !strcmp(ptype, "mixed"))) { - xSubList = XMLRPC_CreateVector("member", xmlrpc_vector_array); - - if(xSubList) { - xml_element* elem_iter = Q_Head(&el->children); - while(elem_iter) { - XMLRPC_AddValueToVector(xSubList, - xml_element_to_method_description(elem_iter, err)); - elem_iter = Q_Next(&el->children); - } - } - } - xReturn = describeValue_worker(ptype, name, (desc ? desc : (xSubList ? NULL : el->text.str)), optional, def, xSubList); - } - } - - /* these three kids are about equivalent */ - else if(!strcmp(el->name, "params") || - !strcmp(el->name, "returns") || - !strcmp(el->name, "signature")) { - if(Q_Size(&el->children)) { - xml_element* elem_iter = Q_Head(&el->children); - xReturn = XMLRPC_CreateVector(!strcmp(el->name, "signature") ? NULL : el->name, xmlrpc_vector_struct); - - - while(elem_iter) { - XMLRPC_AddValueToVector(xReturn, - xml_element_to_method_description(elem_iter, err)); - elem_iter = Q_Next(&el->children); - } - } - } - - - else if(!strcmp(el->name, "methodDescription")) { - xml_element* elem_iter = Q_Head(&el->children); - xReturn = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); - - XMLRPC_VectorAppendString(xReturn, xi_token_name, name, 0); - - while(elem_iter) { - XMLRPC_AddValueToVector(xReturn, - xml_element_to_method_description(elem_iter, err)); - elem_iter = Q_Next(&el->children); - } - } - - /* items are slightly special */ - else if(!strcmp(el->name, "item")) { - xReturn = XMLRPC_CreateValueString(name, el->text.str, el->text.len); - } - - /* sure. we'll let any ol element with children through */ - else if(Q_Size(&el->children)) { - xml_element* elem_iter = Q_Head(&el->children); - xReturn = XMLRPC_CreateVector(el->name, xmlrpc_vector_mixed); - - while(elem_iter) { - XMLRPC_AddValueToVector(xReturn, - xml_element_to_method_description(elem_iter, err)); - elem_iter = Q_Next(&el->children); - } - } - - /* or anything at all really, so long as its got some text. - * no reason being all snotty about a spec, right? - */ - else if(el->name && el->text.len) { - xReturn = XMLRPC_CreateValueString(el->name, el->text.str, el->text.len); - } - } - - return xReturn; -} - -/*-**************************** -* End Introspection Utilities * -******************************/ - - - -/*-****************** -* Introspection API * -********************/ - - -/****f* VALUE/XMLRPC_IntrospectionCreateDescription - * NAME - * XMLRPC_IntrospectionCreateDescription - * SYNOPSIS - * XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR err) - * FUNCTION - * converts raw xml describing types and methods into an - * XMLRPC_VALUE suitable for use with XMLRPC_ServerAddIntrospectionData() - * INPUTS - * xml - xml data conforming to introspection spec at - * err - optional pointer to error struct. filled in if error occurs and not NULL. - * RESULT - * XMLRPC_VALUE - newly created value, or NULL if fatal error. - * BUGS - * Currently does little or no validation of xml. - * Only parse errors are currently reported in err, not structural errors. - * SEE ALSO - * XMLRPC_ServerAddIntrospectionData () - * SOURCE - */ -XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR err) { - XMLRPC_VALUE xReturn = NULL; - xml_element* root = xml_elem_parse_buf(xml, 0, 0, err ? &err->xml_elem_error : NULL); - - if(root) { - xReturn = xml_element_to_method_description(root, err); - - xml_elem_free(root); - } - - return xReturn; - -} -/*******/ - - -/****f* SERVER/XMLRPC_ServerAddIntrospectionData - * NAME - * XMLRPC_ServerAddIntrospectionData - * SYNOPSIS - * int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) - * FUNCTION - * updates server with additional introspection data - * INPUTS - * server - target server - * desc - introspection data, should be a struct generated by - * XMLRPC_IntrospectionCreateDescription () - * RESULT - * int - 1 if success, else 0 - * NOTES - * - function will fail if neither typeList nor methodList key is present in struct. - * - if method or type already exists, it will be replaced. - * - desc is never freed by the server. caller is responsible for cleanup. - * BUGS - * - horribly slow lookups. prime candidate for hash improvements. - * - uglier and more complex than I like to see for API functions. - * SEE ALSO - * XMLRPC_ServerAddIntrospectionData () - * XMLRPC_ServerRegisterIntrospectionCallback () - * XMLRPC_CleanupValue () - * SOURCE - */ -int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) { - int bSuccess = 0; - if(server && desc) { - XMLRPC_VALUE xNewTypes = XMLRPC_VectorGetValueWithID(desc, "typeList"); - XMLRPC_VALUE xNewMethods = XMLRPC_VectorGetValueWithID(desc, "methodList"); - XMLRPC_VALUE xServerTypes = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); - - if(xNewMethods) { - XMLRPC_VALUE xMethod = XMLRPC_VectorRewind(xNewMethods); - - while(xMethod) { - const char* name = XMLRPC_VectorGetStringWithID(xMethod, xi_token_name); - server_method* sm = find_method(server, name); - - if(sm) { - if(sm->desc) { - XMLRPC_CleanupValue(sm->desc); - } - sm->desc = XMLRPC_CopyValue(xMethod); - bSuccess = 1; - } - - xMethod = XMLRPC_VectorNext(xNewMethods); - } - } - if(xNewTypes) { - if(!xServerTypes) { - if(!server->xIntrospection) { - server->xIntrospection = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); - } - - XMLRPC_AddValueToVector(server->xIntrospection, xNewTypes); - bSuccess = 1; - } - else { - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xNewTypes); - while(xIter) { - /* get rid of old values */ - XMLRPC_VALUE xPrev = find_named_value(xServerTypes, XMLRPC_VectorGetStringWithID(xIter, xi_token_name)); - if(xPrev) { - XMLRPC_VectorRemoveValue(xServerTypes, xPrev); - } - XMLRPC_AddValueToVector(xServerTypes, xIter); - bSuccess = 1; - xIter = XMLRPC_VectorNext(xNewTypes); - } - } - } - } - return bSuccess; -} -/*******/ - - -/****f* SERVER/XMLRPC_ServerRegisterIntrospectionCallback - * NAME - * XMLRPC_ServerRegisterIntrospectionCallback - * SYNOPSIS - * int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb) - * FUNCTION - * registers a callback for lazy generation of introspection data - * INPUTS - * server - target server - * cb - callback that will generate introspection data - * RESULT - * int - 1 if success, else 0 - * NOTES - * parsing xml and generating introspection data is fairly expensive, thus a - * server may wish to wait until this data is actually requested before generating - * it. Any number of callbacks may be registered at any time. A given callback - * will only ever be called once, the first time an introspection request is - * processed after the time of callback registration. - * SEE ALSO - * XMLRPC_ServerAddIntrospectionData () - * XMLRPC_IntrospectionCreateDescription () - * SOURCE - */ -int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb) { - int bSuccess = 0; - if(server && cb) { - - doc_method* dm = calloc(1, sizeof(doc_method)); - - if(dm) { - dm->method = cb; - dm->b_called = 0; - - if(Q_PushTail(&server->docslist, dm)) { - bSuccess = 1; - } - else { - my_free(dm); - } - } - } - return 0; -} -/*******/ - -/*-********************** -* End Introspection API * -************************/ - - - diff --git a/php/xmlrpc/libxmlrpc/xmlrpc_introspection.h b/php/xmlrpc/libxmlrpc/xmlrpc_introspection.h deleted file mode 100644 index 656e441..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc_introspection.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* IMPORTANT! - * - * only public (official API) things should be in this file. Anything else - * should go in _private.h, or in the appropriate .c file. - */ - - -#ifndef __XI_INTROSPECTION_H -/* - * Avoid include redundancy. - */ -#define __XI_INTROSPECTION_H - -/*---------------------------------------------------------------------------- - * xmlrpc_introspection.h - * - * Purpose: - * define public introspection API - * Comments: - */ - -/*---------------------------------------------------------------------------- - * Constants - */ - #define xi_token_params "params" - #define xi_token_returns "returns" - #define xi_token_related "related" - #define xi_token_sub "sub" - - -/*---------------------------------------------------------------------------- - * Includes - */ - -/*---------------------------------------------------------------------------- - * Structures - */ - - /****d* VALUE/XMLRPC_IntrospectionCallback - * NAME - * XMLRPC_IntrospectionCallback - * NOTES - * Function prototype for lazy documentation generation (not generated until requested). - * SOURCE - */ -typedef void (*XMLRPC_IntrospectionCallback)(XMLRPC_SERVER server, void* userData); -/******/ - - -/*---------------------------------------------------------------------------- - * Globals - */ - -/*---------------------------------------------------------------------------- - * Functions - */ -XMLRPC_VALUE XMLRPC_IntrospectionCreateDescription(const char* xml, XMLRPC_ERROR error); -int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc); -int XMLRPC_ServerRegisterIntrospectionCallback(XMLRPC_SERVER server, XMLRPC_IntrospectionCallback cb); - -/*---------------------------------------------------------------------------- - * Macros - */ - - -#endif /* __XI_INTROSPECTION_H */ - - - diff --git a/php/xmlrpc/libxmlrpc/xmlrpc_introspection_private.h b/php/xmlrpc/libxmlrpc/xmlrpc_introspection_private.h deleted file mode 100644 index 7b97fa7..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc_introspection_private.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Dan Libby, Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* IMPORTANT! - * - * only non-public things should be in this file. It is fine for any .c file - * in xmlrpc/src to include it, but users of the public API should never - * include it, and thus *.h files that are part of the public API should - * never include it, or they would break if this file is not present. - */ - - -#ifndef __XI_INTROSPECTION_PRIVATE_H -/* - * Avoid include redundancy. - */ -#define __XI_INTROSPECTION_PRIVATE_H - -/*---------------------------------------------------------------------------- - * xmlrpc_introspection_private.h - * - * Purpose: - * define non-public introspection routines - * Comments: - */ - -/*---------------------------------------------------------------------------- - * Constants - */ -#define xi_token_default "default" -#define xi_token_description "description" -#define xi_token_name "name" -#define xi_token_optional "optional" -#define xi_token_params "params" -#define xi_token_purpose "purpose" -#define xi_token_returns "returns" -#define xi_token_signatures "signatures" -#define xi_token_type "type" -#define xi_token_version "version" -#define xi_token_empty "" -#define xi_token_system_describe_methods "system.describeMethods" -#define xi_token_system_list_methods "system.listMethods" -#define xi_token_system_method_help "system.methodHelp" -#define xi_token_system_method_signature "system.methodSignature" - - -/*---------------------------------------------------------------------------- - * Includes - */ - -/*---------------------------------------------------------------------------- - * Structures - */ -typedef struct _doc_method { - XMLRPC_IntrospectionCallback method; - int b_called; -} doc_method; - -/*---------------------------------------------------------------------------- - * Globals - */ - -/*---------------------------------------------------------------------------- - * Functions - */ -void xi_register_system_methods(XMLRPC_SERVER server); - -/*---------------------------------------------------------------------------- - * Macros - */ - - -#endif /* __XI_INTROSPECTION_PRIVATE_H */ - - - - diff --git a/php/xmlrpc/libxmlrpc/xmlrpc_private.h b/php/xmlrpc/libxmlrpc/xmlrpc_private.h deleted file mode 100644 index 65c6b13..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc_private.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* only non-public things should be in this file. It is fine for any .c file - * in xmlrpc/src to include it, but users of the public API should never - * include it, and thus *.h files that are part of the public API should - * never include it, or they would break if this file is not present. - */ - -#ifndef XMLRPC_PRIVATE_ALREADY_INCLUDED -/* - * Avoid include redundancy. - */ -#define XMLRPC_PRIVATE_ALREADY_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - - -/*---------------------------------------------------------------------------- - * xmlrpc_private.h - * - * Purpose: - * define non-public intra-library routines & data - * Comments: - */ - -/*---------------------------------------------------------------------------- - * Constants - */ - - -/*---------------------------------------------------------------------------- - * Includes - */ - -/*---------------------------------------------------------------------------- - * Structures - */ - -/* Some of these are typedef'd in xmlrpc.h for public use */ - -typedef struct _xmlrpc_vector* XMLRPC_VECTOR; - -/****s* VALUE/XMLRPC_VALUE - * NAME - * XMLRPC_VALUE - * NOTES - * A value of variable data type. The most important object in this API. :) - * - * This struct is opaque to callers and should be accessed only via accessor functions. - * SEE ALSO - * XMLRPC_REQUEST - * XMLRPC_CreateValueEmpty () - * XMLRPC_CleanupValue () - * SOURCE - */ -typedef struct _xmlrpc_value { - XMLRPC_VALUE_TYPE type; /* data type of this value */ - XMLRPC_VECTOR v; /* vector type specific info */ - simplestring str; /* string value buffer */ - simplestring id; /* id of this value. possibly empty. */ - int i; /* integer value. */ - double d; /* double value */ - int iRefCount; /* So we know when we can delete the value . */ -} STRUCT_XMLRPC_VALUE; -/******/ - -/****s* VALUE/XMLRPC_REQUEST - * NAME - * XMLRPC_REQUEST - * NOTES - * Internal representation of an XML request. - * - * This struct is opaque to callers and should be accessed only via accessor functions. - * - * SEE ALSO - * XMLRPC_VALUE - * XMLRPC_RequestNew () - * XMLRPC_RequestFree () - * SOURCE - */ -typedef struct _xmlrpc_request { - XMLRPC_VALUE io; /* data associated with this request */ - simplestring methodName; /* name of method being called */ - XMLRPC_REQUEST_TYPE request_type; /* type of request */ - STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS output; /* xml output options */ - XMLRPC_VALUE error; /* error codes */ -} STRUCT_XMLRPC_REQUEST; -/******/ - -/* Vector type. Used by XMLRPC_VALUE. Never visible to users of the API. */ -typedef struct _xmlrpc_vector { - XMLRPC_VECTOR_TYPE type; /* vector type */ - queue *q; /* list of child values */ -} STRUCT_XMLRPC_VECTOR; -/******/ - -/****s* VALUE/XMLRPC_SERVER - * NAME - * XMLRPC_SERVER - * NOTES - * internal representation of an xmlrpc server - * - * This struct is opaque to callers and should be accessed only via accessor functions. - * - * SEE ALSO - * XMLRPC_ServerCreate () - * XMLRPC_ServerDestroy () - * SOURCE - */ -typedef struct _xmlrpc_server { - queue methodlist; /* list of callback methods */ - queue docslist; /* list of introspection callbacks */ - XMLRPC_VALUE xIntrospection; -} STRUCT_XMLRPC_SERVER; -/******/ - -typedef struct _server_method { - char* name; - XMLRPC_VALUE desc; - XMLRPC_Callback method; -} server_method; - - -/*---------------------------------------------------------------------------- - * Globals - */ - -/*---------------------------------------------------------------------------- - * Functions - */ -server_method* find_method(XMLRPC_SERVER server, const char* name); -const char* type_to_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype); - -/*---------------------------------------------------------------------------- - * Macros - */ -#define my_free(thing) if(thing) {free(thing); thing = 0;} - - -#ifdef __cplusplus -} -#endif - - -#endif /* XMLRPC_PRIVATE_ALREADY_INCLUDED */ - diff --git a/php/xmlrpc/libxmlrpc/xmlrpc_win32.h b/php/xmlrpc/libxmlrpc/xmlrpc_win32.h deleted file mode 100644 index 58c54bb..0000000 --- a/php/xmlrpc/libxmlrpc/xmlrpc_win32.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _XMLRPC_WIN32_H -#define _XMLRPC_WIN32_H -/* just some things needed to compile win32 */ -#include -#include -#define inline __inline -#define snprintf _snprintf -#define strcasecmp(s1, s2) stricmp(s1, s2) - - -#endif \ No newline at end of file diff --git a/php/xmlrpc/php_xmlrpc.h b/php/xmlrpc/php_xmlrpc.h deleted file mode 100644 index 98355ba..0000000 --- a/php/xmlrpc/php_xmlrpc.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - This file is part of, or distributed with, libXMLRPC - a C library for - xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* auto-generated portions of this file are also subject to the php license */ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Dan Libby | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -#ifndef _PHP_XMLRPC_H -#define _PHP_XMLRPC_H - -/* You should tweak config.m4 so this symbol (or some else suitable) - gets defined. -*/ -#if 1 /* HAVE_XMLRPC */ - -extern zend_module_entry xmlrpc_module_entry; -#define phpext_xmlrpc_ptr &xmlrpc_module_entry - -#ifdef PHP_WIN32 -#define PHP_XMLRPC_API __declspec(dllexport) -#else -#define PHP_XMLRPC_API -#endif - -PHP_MINIT_FUNCTION(xmlrpc); -PHP_MSHUTDOWN_FUNCTION(xmlrpc); -PHP_RINIT_FUNCTION(xmlrpc); -PHP_RSHUTDOWN_FUNCTION(xmlrpc); -PHP_MINFO_FUNCTION(xmlrpc); - -PHP_FUNCTION(xmlrpc_encode); -PHP_FUNCTION(xmlrpc_decode); -PHP_FUNCTION(xmlrpc_decode_request); -PHP_FUNCTION(xmlrpc_encode_request); -PHP_FUNCTION(xmlrpc_get_type); -PHP_FUNCTION(xmlrpc_set_type); -PHP_FUNCTION(xmlrpc_is_fault); -PHP_FUNCTION(xmlrpc_server_create); -PHP_FUNCTION(xmlrpc_server_destroy); -PHP_FUNCTION(xmlrpc_server_register_method); -PHP_FUNCTION(xmlrpc_server_call_method); -PHP_FUNCTION(xmlrpc_parse_method_descriptions); -PHP_FUNCTION(xmlrpc_server_add_introspection_data); -PHP_FUNCTION(xmlrpc_server_register_introspection_callback); - -/* Fill in this structure and use entries in it - for thread safety instead of using true globals. -*/ -ZEND_BEGIN_MODULE_GLOBALS(xmlrpc) - long allow_null; -ZEND_END_MODULE_GLOBALS(xmlrpc) - -/* In every function that needs to use variables in zend_xmlrpc_globals, - do call XMLRPCLS_FETCH(); after declaring other variables used by - that function, and always refer to them as XMLRPCG(variable). - You are encouraged to rename these macros something shorter, see - examples in any other php module directory. -*/ - -#ifdef ZTS -#define XMLRPCG(v) TSRMG(xmlrpc_globals_id, zend_xmlrpc_globals *, v) -#define XMLRPCLS_FETCH() zend_xmlrpc_globals *xmlrpc_globals = ts_resource(xmlrpc_globals_id) -#else -#define XMLRPCG(v) (xmlrpc_globals.v) -#define XMLRPCLS_FETCH() -#endif - -ZEND_EXTERN_MODULE_GLOBALS(xmlrpc) - -#else - -#define phpext_xmlrpc_ptr NULL - -#endif - -#endif /* _PHP_XMLRPC_H */ - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/php/xmlrpc/xmlrpc-epi-php.c b/php/xmlrpc/xmlrpc-epi-php.c deleted file mode 100644 index c2dc4e0..0000000 --- a/php/xmlrpc/xmlrpc-epi-php.c +++ /dev/null @@ -1,1587 +0,0 @@ -/* - This file is part of, or distributed with, libXMLRPC - a C library for - xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2001 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - -/* auto-generated portions of this file are also subject to the php license */ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2004 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Dan Libby | - +----------------------------------------------------------------------+ - */ - -/********************************************************************** -* BUGS: * -* - when calling a php user function, there appears to be no way to * -* distinguish between a return value of null, and no return value * -* at all. The xml serialization layer(s) will then return a value * -* of null, when the right thing may be no value at all. (SOAP) * -**********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "ext/standard/info.h" -#include "php_ini.h" -#include "php_xmlrpc.h" -#include "xmlrpc.h" - -#define PHP_EXT_VERSION "0.51" - -/* ==================== - * Thierry - Dec. 17 2009 - * patch for php - bug first triggered on f12 with php-5.3 - * http://pecl.php.net/bugs/bug.php?id=14369 - * http://remi.fedorapeople.org/ncurses-1.0.0-php53.patch - * I'm taking out the 'static' stuff as after pre-processing it appears to be part of the macro expansion already - */ -#if ZEND_MODULE_API_NO >= 20071006 -// No more defined with PHP 5.3.0 - ZEND_BEGIN_ARG_INFO(first_arg_force_ref, 0) - ZEND_ARG_PASS_INFO(1) - ZEND_END_ARG_INFO(); - - ZEND_BEGIN_ARG_INFO(second_arg_force_ref, 0) - ZEND_ARG_PASS_INFO(0) - ZEND_ARG_PASS_INFO(1) - ZEND_END_ARG_INFO(); -#endif -/* ==================== end patch */ - -/* ==================== - * Thierry - Jan. 30 2013 - * patch for php - issues first triggered on f18 with php-5.4 - * https://bugs.php.net/bug.php?id=60016 - * https://bugs.php.net/bug.php?id=60016 - */ -#if ZEND_MODULE_API_NO >= 20100525 -// No more defined with PHP 5.4 -#define function_entry zend_function_entry -#define pval zval -#endif -/* ==================== end patch */ - -/* ==================== - * Thierry - Jan. 2 2015 - * patch for php - issues first triggered on f21 with php-5.6 - * somebody somehow seems to have undefined - * the IS_CONSTANT_ARRAY constant - * - * however I'd rather not change the code that runs - * on older releases, so see for the ugly ifdef below - * -/* ==================== end patch */ - - -/* ========== additional notes - * in the process, I've also come across the following resources that might help - * if/when zend_get_parameters_ex gets deprecated (only generates warnings for now) - * - * http://developers.evrsoft.com/docs/php/zend.arguments.deprecated-retrieval.shtml - * explains how the old (our) stuff works - * - * http://www.hospedajeydominios.com/mambo/documentacion-manual_php-pagina-zend_arguments_retrieval.html - * gives info on the new scheme - * - * I'm taking tha risk as the changes seem to mean major surgery ... - */ - -/* You should tweak config.m4 so this symbol (or some else suitable) - gets defined. */ - -ZEND_DECLARE_MODULE_GLOBALS(xmlrpc) - -static int le_xmlrpc_server; - -function_entry xmlrpc_functions[] = { - PHP_FE(xmlrpc_encode, NULL) - PHP_FE(xmlrpc_decode, NULL) - PHP_FE(xmlrpc_decode_request, second_arg_force_ref) - PHP_FE(xmlrpc_encode_request, NULL) - PHP_FE(xmlrpc_get_type, NULL) - PHP_FE(xmlrpc_set_type, first_arg_force_ref) - PHP_FE(xmlrpc_is_fault, NULL) - PHP_FE(xmlrpc_server_create, NULL) - PHP_FE(xmlrpc_server_destroy, NULL) - PHP_FE(xmlrpc_server_register_method, NULL) - PHP_FE(xmlrpc_server_call_method, NULL) - PHP_FE(xmlrpc_parse_method_descriptions, NULL) - PHP_FE(xmlrpc_server_add_introspection_data, NULL) - PHP_FE(xmlrpc_server_register_introspection_callback, NULL) - {NULL, NULL, NULL} -}; - -zend_module_entry xmlrpc_module_entry = { - STANDARD_MODULE_HEADER, - "xmlrpc", - xmlrpc_functions, - PHP_MINIT(xmlrpc), - PHP_MSHUTDOWN(xmlrpc), - PHP_RINIT(xmlrpc), /* Replace with NULL if there's nothing to do at request start */ - PHP_RSHUTDOWN(xmlrpc), /* Replace with NULL if there's nothing to do at request end */ - PHP_MINFO(xmlrpc), - PHP_EXT_VERSION, - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_XMLRPC -ZEND_GET_MODULE(xmlrpc) -# ifdef PHP_WIN32 -# include "zend_arg_defs.c" -# endif -#endif - -PHP_INI_BEGIN() -STD_PHP_INI_BOOLEAN("xmlrpc.allow_null", "0", PHP_INI_ALL, OnUpdateBool, allow_null, zend_xmlrpc_globals, xmlrpc_globals) -PHP_INI_END() - -static void php_xmlrpc_init_globals(zend_xmlrpc_globals *xmlrpc_globals) -{ - memset(xmlrpc_globals, 0, sizeof(zend_xmlrpc_globals)); -} - -/******************************* -* local structures and defines * -*******************************/ - -/* per server data */ -typedef struct _xmlrpc_server_data { - zval* method_map; - zval* introspection_map; - XMLRPC_SERVER server_ptr; -} xmlrpc_server_data; - - -/* how to format output */ -typedef struct _php_output_options { - int b_php_out; - int b_auto_version; - int b_allow_null; - STRUCT_XMLRPC_REQUEST_OUTPUT_OPTIONS xmlrpc_out; -} php_output_options; - -/* data passed to C callback */ -typedef struct _xmlrpc_callback_data { - zval* xmlrpc_method; - zval* php_function; - zval* caller_params; - zval* return_data; - xmlrpc_server_data* server; - char php_executed; -} xmlrpc_callback_data; - -/* output options */ -#define OUTPUT_TYPE_KEY "output_type" -#define OUTPUT_TYPE_KEY_LEN (sizeof(OUTPUT_TYPE_KEY) - 1) -#define OUTPUT_TYPE_VALUE_PHP "php" -#define OUTPUT_TYPE_VALUE_XML "xml" - -#define ALLOW_NULL_KEY "allow_null" -#define ALLOW_NULL_KEY_LEN (sizeof(ALLOW_NULL_KEY) - 1) - -#define VERBOSITY_KEY "verbosity" -#define VERBOSITY_KEY_LEN (sizeof(VERBOSITY_KEY) - 1) -#define VERBOSITY_VALUE_NO_WHITE_SPACE "no_white_space" -#define VERBOSITY_VALUE_NEWLINES_ONLY "newlines_only" -#define VERBOSITY_VALUE_PRETTY "pretty" - -#define ESCAPING_KEY "escaping" -#define ESCAPING_KEY_LEN (sizeof(ESCAPING_KEY) - 1) -#define ESCAPING_VALUE_CDATA "cdata" -#define ESCAPING_VALUE_NON_ASCII "non-ascii" -#define ESCAPING_VALUE_NON_PRINT "non-print" -#define ESCAPING_VALUE_MARKUP "markup" - -#define VERSION_KEY "version" -#define VERSION_KEY_LEN (sizeof(VERSION_KEY) - 1) -#define VERSION_VALUE_SIMPLE "simple" -#define VERSION_VALUE_XMLRPC "xmlrpc" -#define VERSION_VALUE_SOAP11 "soap 1.1" -#define VERSION_VALUE_AUTO "auto" - -#define ENCODING_KEY "encoding" -#define ENCODING_KEY_LEN (sizeof(ENCODING_KEY) - 1) -#define ENCODING_DEFAULT "iso-8859-1" - -/* value types */ -#define OBJECT_TYPE_ATTR "xmlrpc_type" -#define OBJECT_VALUE_ATTR "scalar" -#define OBJECT_VALUE_TS_ATTR "timestamp" - -/* faults */ -#define FAULT_CODE "faultCode" -#define FAULT_CODE_LEN (sizeof(FAULT_CODE) - 1) -#define FAULT_STRING "faultString" -#define FAULT_STRING_LEN (sizeof(FAULT_STRING) - 1) - -/*********************** -* forward declarations * -***********************/ -XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(php_output_options* out, zval* value, zval** newvalue); -static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data); -int sset_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type); -zval* decode_request_worker(zval* xml_in, zval* encoding_in, zval* method_name_out); -const char* xmlrpc_type_as_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype); -XMLRPC_VALUE_TYPE xmlrpc_str_as_type(const char* str); -XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str); -int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE type); - -/********************* -* startup / shutdown * -*********************/ - -static void destroy_server_data(xmlrpc_server_data *server) -{ - if (server) { - XMLRPC_ServerDestroy(server->server_ptr); - - zval_dtor(server->method_map); - FREE_ZVAL(server->method_map); - - zval_dtor(server->introspection_map); - FREE_ZVAL(server->introspection_map); - - efree(server); - } -} - -/* called when server is being destructed. either when xmlrpc_server_destroy - * is called, or when request ends. */ -static void xmlrpc_server_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - if (rsrc && rsrc->ptr) { - destroy_server_data((xmlrpc_server_data*) rsrc->ptr); - } -} - -/* module init */ -PHP_MINIT_FUNCTION(xmlrpc) -{ - ZEND_INIT_MODULE_GLOBALS(xmlrpc, php_xmlrpc_init_globals, NULL); - - REGISTER_INI_ENTRIES(); - - le_xmlrpc_server = zend_register_list_destructors_ex(xmlrpc_server_destructor, NULL, "xmlrpc server", module_number); - - return SUCCESS; -} - -/* module shutdown */ -PHP_MSHUTDOWN_FUNCTION(xmlrpc) -{ - return SUCCESS; -} - -/* Remove if there's nothing to do at request start */ -PHP_RINIT_FUNCTION(xmlrpc) -{ - return SUCCESS; -} - -/* Remove if there's nothing to do at request end */ -PHP_RSHUTDOWN_FUNCTION(xmlrpc) -{ - return SUCCESS; -} - -/* display info in phpinfo() */ -PHP_MINFO_FUNCTION(xmlrpc) -{ - php_info_print_table_start(); - php_info_print_table_row(2, "core library version", XMLRPC_GetVersionString()); - php_info_print_table_row(2, "php extension version", PHP_EXT_VERSION); - php_info_print_table_row(2, "author", "Dan Libby"); - php_info_print_table_row(2, "homepage", "http://xmlrpc-epi.sourceforge.net"); - php_info_print_table_row(2, "open sourced by", "Epinions.com"); - php_info_print_table_end(); -} - -/******************* -* random utilities * -*******************/ - -/* Utility functions for adding data types to arrays, with or without key (assoc, non-assoc). - * Could easily be further generalized to work with objects. - */ -#if 0 -static int add_long(zval* list, char* id, int num) { - if(id) return add_assoc_long(list, id, num); - else return add_next_index_long(list, num); -} - -static int add_double(zval* list, char* id, double num) { - if(id) return add_assoc_double(list, id, num); - else return add_next_index_double(list, num); -} - -static int add_string(zval* list, char* id, char* string, int duplicate) { - if(id) return add_assoc_string(list, id, string, duplicate); - else return add_next_index_string(list, string, duplicate); -} - -static int add_stringl(zval* list, char* id, char* string, uint length, int duplicate) { - if(id) return add_assoc_stringl(list, id, string, length, duplicate); - else return add_next_index_stringl(list, string, length, duplicate); -} - -#endif - -static int add_zval(zval* list, const char* id, zval** val) -{ - if (list && val) { - if (id) { - return zend_hash_update(Z_ARRVAL_P(list), (char*) id, strlen(id) + 1, (void *) val, sizeof(zval **), NULL); - } else { - return zend_hash_next_index_insert(Z_ARRVAL_P(list), (void *) val, sizeof(zval **), NULL); - } - } - /* what is the correct return on error? */ - return 0; -} - -#define my_zend_hash_get_current_key(ht, my_key, num_index) zend_hash_get_current_key(ht, my_key, num_index, 0) - - -/************************* -* input / output options * -*************************/ - -/* parse an array (user input) into output options suitable for use by xmlrpc engine - * and determine whether to return data as xml or php vars */ -static void set_output_options(php_output_options* options, zval* output_opts) -{ - XMLRPCLS_FETCH(); - - if (options) { - - /* defaults */ - options->b_php_out = 0; - options->b_auto_version = 1; - options->b_allow_null = 0; - options->xmlrpc_out.version = xmlrpc_version_1_0; - options->xmlrpc_out.xml_elem_opts.encoding = ENCODING_DEFAULT; - options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_pretty; - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping | xml_elem_non_ascii_escaping | xml_elem_non_print_escaping; - - if (output_opts && Z_TYPE_P(output_opts) == IS_ARRAY) { - zval** val; - - /* marshal NULL */ - if (zend_hash_find(Z_ARRVAL_P(output_opts), ALLOW_NULL_KEY, ALLOW_NULL_KEY_LEN + 1, (void**) &val) == SUCCESS) { - if (Z_TYPE_PP(val) == IS_BOOL) { - if (Z_LVAL_PP(val)) { - options->b_allow_null = 1; - } else { - options->b_allow_null = 0; - } - } - } - - /* type of output (xml/php) */ - if (zend_hash_find(Z_ARRVAL_P(output_opts), OUTPUT_TYPE_KEY, OUTPUT_TYPE_KEY_LEN + 1, (void**) &val) == SUCCESS) { - if (Z_TYPE_PP(val) == IS_STRING) { - if (!strcmp(Z_STRVAL_PP(val), OUTPUT_TYPE_VALUE_PHP)) { - options->b_php_out = 1; - } else if (!strcmp(Z_STRVAL_PP(val), OUTPUT_TYPE_VALUE_XML)) { - options->b_php_out = 0; - } - } - } - - /* verbosity of generated xml */ - if (zend_hash_find(Z_ARRVAL_P(output_opts), VERBOSITY_KEY, VERBOSITY_KEY_LEN + 1, (void**) &val) == SUCCESS) { - if (Z_TYPE_PP(val) == IS_STRING) { - if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_NO_WHITE_SPACE)) { - options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_no_white_space; - } else if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_NEWLINES_ONLY)) { - options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_newlines_only; - } else if (!strcmp(Z_STRVAL_PP(val), VERBOSITY_VALUE_PRETTY)) { - options->xmlrpc_out.xml_elem_opts.verbosity = xml_elem_pretty; - } - } - } - - /* version of xml to output */ - if (zend_hash_find(Z_ARRVAL_P(output_opts), VERSION_KEY, VERSION_KEY_LEN + 1, (void**) &val) == SUCCESS) { - if (Z_TYPE_PP(val) == IS_STRING) { - options->b_auto_version = 0; - if (!strcmp(Z_STRVAL_PP(val), VERSION_VALUE_XMLRPC)) { - options->xmlrpc_out.version = xmlrpc_version_1_0; - } else if (!strcmp(Z_STRVAL_PP(val), VERSION_VALUE_SIMPLE)) { - options->xmlrpc_out.version = xmlrpc_version_simple; - } else if (!strcmp((*val)->value.str.val, VERSION_VALUE_SOAP11)) { - options->xmlrpc_out.version = xmlrpc_version_soap_1_1; - } else { /* if(!strcmp((*val)->value.str.val, VERSION_VALUE_AUTO)) { */ - options->b_auto_version = 1; - } - } - } - - /* encoding code set */ - if(zend_hash_find(Z_ARRVAL_P(output_opts), - ENCODING_KEY, ENCODING_KEY_LEN + 1, - (void**)&val) == SUCCESS) { - if(Z_TYPE_PP(val) == IS_STRING) { - options->xmlrpc_out.xml_elem_opts.encoding = estrdup(Z_STRVAL_PP(val)); - } - } - - /* escaping options */ - if(zend_hash_find(Z_ARRVAL_P(output_opts), - ESCAPING_KEY, ESCAPING_KEY_LEN + 1, - (void**)&val) == SUCCESS) { - /* multiple values allowed. check if array */ - if(Z_TYPE_PP(val) == IS_ARRAY) { - zval** iter_val; - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val)); - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_no_escaping; - while(1) { - if(zend_hash_get_current_data(Z_ARRVAL_PP(val), (void**)&iter_val) == SUCCESS) { - if(Z_TYPE_PP(iter_val) == IS_STRING && Z_STRVAL_PP(iter_val)) { - if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_CDATA)) { - options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_cdata_escaping; - } - else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_ASCII)) { - options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_ascii_escaping; - } - else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_PRINT)) { - options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_print_escaping; - } - else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_MARKUP)) { - options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_markup_escaping; - } - } - } - else { - break; - } - - zend_hash_move_forward(Z_ARRVAL_PP(val)); - } - } - /* else, check for single value */ - else if(Z_TYPE_PP(val) == IS_STRING) { - if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_CDATA)) { - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_cdata_escaping; - } - else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_ASCII)) { - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_ascii_escaping; - } - else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_PRINT)) { - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_print_escaping; - } - else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_MARKUP)) { - options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping; - } - } - } - } - } -} - - -/****************** -* encode / decode * -******************/ - -/* php arrays have no distinction between array and struct types. - * they even allow mixed. Thus, we determine the type by iterating - * through the entire array and figuring out each element. - * room for some optimation here if we stop after a specific # of elements. - */ -static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht) -{ - int bArray = 0, bStruct = 0, bMixed = 0; - unsigned long num_index; - char* my_key; - - zend_hash_internal_pointer_reset(ht); - while(1) { - int res = my_zend_hash_get_current_key(ht, &my_key, &num_index); - if(res == HASH_KEY_IS_LONG) { - if(bStruct) { - bMixed = 1; - break; - } - bArray = 1; - } - else if(res == HASH_KEY_NON_EXISTANT) { - break; - } - else if(res == HASH_KEY_IS_STRING) { - if(bArray) { - bMixed = 1; - break; - } - bStruct = 1; - } - - zend_hash_move_forward(ht); - } - return bMixed ? xmlrpc_vector_mixed : (bStruct ? xmlrpc_vector_struct : xmlrpc_vector_array); -} - -/* recursively convert php values into xmlrpc values */ -static XMLRPC_VALUE PHP_to_XMLRPC_worker (php_output_options* out, const char* key, zval* in_val, int depth) -{ - XMLRPC_VALUE xReturn = NULL; - if(in_val) { - zval* val = NULL; - XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(out, in_val, &val); - if(val) { - switch(type) { - case xmlrpc_nil: - xReturn = XMLRPC_CreateValueEmpty(); - XMLRPC_SetValueID(xReturn, key, 0); - break; - case xmlrpc_base64: - xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); - break; - case xmlrpc_datetime: - convert_to_string(val); - xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val)); - break; - case xmlrpc_boolean: - convert_to_boolean(val); - xReturn = XMLRPC_CreateValueBoolean(key, Z_LVAL_P(val)); - break; - case xmlrpc_int: - convert_to_long(val); - xReturn = XMLRPC_CreateValueInt(key, Z_LVAL_P(val)); - break; - case xmlrpc_double: - convert_to_double(val); - xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL_P(val)); - break; - case xmlrpc_string: - convert_to_string(val); - xReturn = XMLRPC_CreateValueString(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); - break; - case xmlrpc_vector: - { - unsigned long num_index; - zval** pIter; - char* my_key; - - convert_to_array(val); - - xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(val))); - - zend_hash_internal_pointer_reset(Z_ARRVAL_P(val)); - while(1) { - int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val), &my_key, &num_index); - if(res == HASH_KEY_IS_LONG) { - if(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) { - XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(out, 0, *pIter, depth++)); - } - } - else if(res == HASH_KEY_NON_EXISTANT) { - break; - } - else if(res == HASH_KEY_IS_STRING) { - if(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) { - XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(out, my_key, *pIter, depth++)); - } - } - - zend_hash_move_forward(Z_ARRVAL_P(val)); - } - } - break; - default: - break; - } - } - } - return xReturn; -} - -static XMLRPC_VALUE PHP_to_XMLRPC(php_output_options* out, zval* root_val) -{ - return PHP_to_XMLRPC_worker(out, NULL, root_val, 0); -} - -/* recursively convert xmlrpc values into php values */ -static zval* XMLRPC_to_PHP(XMLRPC_VALUE el) -{ - zval* elem = NULL; - const char* pStr; - - if(el) { - XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(el); - - MAKE_STD_ZVAL(elem); /* init. very important. spent a frustrating day finding this out. */ - - switch(type) { - case xmlrpc_empty: - case xmlrpc_nil: - Z_TYPE_P(elem) = IS_NULL; - break; - case xmlrpc_string: - pStr = XMLRPC_GetValueString(el); - if(pStr) { - Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el); - Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem)); - Z_TYPE_P(elem) = IS_STRING; - } - break; - case xmlrpc_int: - Z_LVAL_P(elem) = XMLRPC_GetValueInt(el); - Z_TYPE_P(elem) = IS_LONG; - break; - case xmlrpc_boolean: - Z_LVAL_P(elem) = XMLRPC_GetValueBoolean(el); - Z_TYPE_P(elem) = IS_BOOL; - break; - case xmlrpc_double: - Z_DVAL_P(elem) = XMLRPC_GetValueDouble(el); - Z_TYPE_P(elem) = IS_DOUBLE; - break; - case xmlrpc_datetime: - Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el); - Z_STRVAL_P(elem) = estrndup(XMLRPC_GetValueDateTime_ISO8601(el), Z_STRLEN_P(elem)); - Z_TYPE_P(elem) = IS_STRING; - break; - case xmlrpc_base64: - pStr = XMLRPC_GetValueBase64(el); - if(pStr) { - Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el); - Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem)); - Z_TYPE_P(elem) = IS_STRING; - } - break; - case xmlrpc_vector: - array_init(elem); - { - XMLRPC_VALUE xIter = XMLRPC_VectorRewind(el); - - while( xIter ) { - zval *val = XMLRPC_to_PHP(xIter); - if (val) { - add_zval(elem, XMLRPC_GetValueID(xIter), &val); - } - xIter = XMLRPC_VectorNext(el); - } - } - break; - default: - break; - } - set_zval_xmlrpc_type(elem, type); - } - return elem; -} - -/* {{{ proto string xmlrpc_encode_request(string method, mixed params) - Generates XML for a method request */ -PHP_FUNCTION(xmlrpc_encode_request) -{ - XMLRPC_REQUEST xRequest = NULL; - zval **method, **vals, **out_opts; - char* outBuf; - php_output_options out; - - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || (zend_get_parameters_ex(ZEND_NUM_ARGS(), &method, &vals, &out_opts) == FAILURE)) { - WRONG_PARAM_COUNT; /* prints/logs a warning and returns */ - } - - set_output_options(&out, (ZEND_NUM_ARGS() == 3) ? *out_opts : 0); - - if(return_value_used) { - xRequest = XMLRPC_RequestNew(); - - if(xRequest) { - XMLRPC_RequestSetOutputOptions(xRequest, &out.xmlrpc_out); - if (Z_TYPE_PP(method) == IS_NULL) { - XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_response); - } else { - XMLRPC_RequestSetMethodName(xRequest, Z_STRVAL_PP(method)); - XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_call); - } - if (Z_TYPE_PP(vals) != IS_NULL) { - XMLRPC_RequestSetData(xRequest, PHP_to_XMLRPC(&out, *vals)); - } - - outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0); - if(outBuf) { - RETVAL_STRING(outBuf, 1); - free(outBuf); - } - XMLRPC_RequestFree(xRequest, 1); - } - } -} -/* }}} */ - -/* {{{ proto string xmlrpc_encode(mixed value) - Generates XML for a PHP value */ -PHP_FUNCTION(xmlrpc_encode) -{ - XMLRPC_VALUE xOut = NULL; - zval **arg1; - char *outBuf; - - if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &arg1) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - if( return_value_used ) { - /* convert native php type to xmlrpc type */ - xOut = PHP_to_XMLRPC(NULL, *arg1); - - /* generate raw xml from xmlrpc data */ - outBuf = XMLRPC_VALUE_ToXML(xOut, 0); - - if(xOut) { - if(outBuf) { - RETVAL_STRING(outBuf, 1); - free(outBuf); - } - /* cleanup */ - XMLRPC_CleanupValue(xOut); - } - } -} -/* }}} */ - - -zval* decode_request_worker (zval* xml_in, zval* encoding_in, zval* method_name_out) -{ - zval* retval = NULL; - XMLRPC_REQUEST response; - STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}}; - opts.xml_elem_opts.encoding = encoding_in ? utf8_get_encoding_id_from_string(Z_STRVAL_P(encoding_in)) : ENCODING_DEFAULT; - - /* generate XMLRPC_REQUEST from raw xml */ - response = XMLRPC_REQUEST_FromXML(Z_STRVAL_P(xml_in), Z_STRLEN_P(xml_in), &opts); - if(response) { - /* convert xmlrpc data to native php types */ - retval = XMLRPC_to_PHP(XMLRPC_RequestGetData(response)); - - if(XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) { - if(method_name_out) { - convert_to_string(method_name_out); - Z_TYPE_P(method_name_out) = IS_STRING; - Z_STRVAL_P(method_name_out) = estrdup(XMLRPC_RequestGetMethodName(response)); - Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out)); - } - } - - /* dust, sweep, and mop */ - XMLRPC_RequestFree(response, 1); - } - return retval; -} - -/* {{{ proto array xmlrpc_decode_request(string xml, string& method [, string encoding]) - Decodes XML into native PHP types */ -PHP_FUNCTION(xmlrpc_decode_request) -{ - zval **xml, **method, **encoding = NULL; - int argc = ZEND_NUM_ARGS(); - - if (argc < 2 || argc > 3 || (zend_get_parameters_ex(argc, &xml, &method, &encoding) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(xml); - convert_to_string_ex(method); - if(argc == 3) { - convert_to_string_ex(encoding); - } - - if(return_value_used) { - zval* retval = decode_request_worker(*xml, encoding ? *encoding : NULL, *method); - if(retval) { - *return_value = *retval; - FREE_ZVAL(retval); - } - } -} -/* }}} */ - - -/* {{{ proto array xmlrpc_decode(string xml [, string encoding]) - Decodes XML into native PHP types */ -PHP_FUNCTION(xmlrpc_decode) -{ - zval **arg1, **arg2 = NULL; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1 || argc > 2 || (zend_get_parameters_ex(argc, &arg1, &arg2) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(arg1); - if(argc == 2) { - convert_to_string_ex(arg2); - } - - if(return_value_used) { - zval* retval = decode_request_worker(*arg1, arg2 ? *arg2 : NULL, NULL); - if(retval) { - *return_value = *retval; - FREE_ZVAL(retval); - } - } -} -/* }}} */ - - -/************************* -* server related methods * -*************************/ - -/* {{{ proto resource xmlrpc_server_create(void) - Creates an xmlrpc server */ -PHP_FUNCTION(xmlrpc_server_create) -{ - if(ZEND_NUM_ARGS() != 0) { - WRONG_PARAM_COUNT; - } - - if(return_value_used) { - zval *method_map, *introspection_map; - xmlrpc_server_data *server = emalloc(sizeof(xmlrpc_server_data)); - MAKE_STD_ZVAL(method_map); - MAKE_STD_ZVAL(introspection_map); - - array_init(method_map); - array_init(introspection_map); - - /* allocate server data. free'd in destroy_server_data() */ - server->method_map = method_map; - server->introspection_map = introspection_map; - server->server_ptr = XMLRPC_ServerCreate(); - - XMLRPC_ServerRegisterIntrospectionCallback(server->server_ptr, php_xmlrpc_introspection_callback); - - /* store for later use */ - ZEND_REGISTER_RESOURCE(return_value,server, le_xmlrpc_server); - } -} -/* }}} */ - -/* {{{ proto int xmlrpc_server_destroy(resource server) - Destroys server resources */ -PHP_FUNCTION(xmlrpc_server_destroy) -{ - zval **arg1; - int bSuccess = FAILURE; - - if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &arg1) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - if(Z_TYPE_PP(arg1) == IS_RESOURCE) { - int type; - - xmlrpc_server_data *server = zend_list_find(Z_LVAL_PP(arg1), &type); - - if(server && type == le_xmlrpc_server) { - bSuccess = zend_list_delete(Z_LVAL_PP(arg1)); - - /* called by hashtable destructor - * destroy_server_data(server); - */ - } - } - RETVAL_LONG(bSuccess == SUCCESS); -} -/* }}} */ - - -/* called by xmlrpc C engine as method handler for all registered methods. - * it then calls the corresponding PHP function to handle the method. - */ -static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server, XMLRPC_REQUEST xRequest, void* data) -{ - xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data; - zval* xmlrpc_params; - zval* callback_params[3]; - TSRMLS_FETCH(); - - /* convert xmlrpc to native php types */ - xmlrpc_params = XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest)); - - /* setup data hoojum */ - callback_params[0] = pData->xmlrpc_method; - callback_params[1] = xmlrpc_params; - callback_params[2] = pData->caller_params; - - /* Use same C function for all methods */ - - /* php func prototype: function user_func($method_name, $xmlrpc_params, $user_params) */ - call_user_function(CG(function_table), NULL, pData->php_function, pData->return_data, 3, callback_params TSRMLS_CC); - - pData->php_executed = 1; - - zval_dtor(xmlrpc_params); - FREE_ZVAL(xmlrpc_params); - - return NULL; -} - -/* called by the C server when it first receives an introspection request. We pass this on to - * our PHP listeners, if any - */ -static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data) -{ - zval *retval_ptr, **php_function; - zval* callback_params[1]; - xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data; - TSRMLS_FETCH(); - - MAKE_STD_ZVAL(retval_ptr); - Z_TYPE_P(retval_ptr) = IS_NULL; - - /* setup data hoojum */ - callback_params[0] = pData->caller_params; - - /* loop through and call all registered callbacks */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pData->server->introspection_map)); - while(1) { - if(zend_hash_get_current_data(Z_ARRVAL_P(pData->server->introspection_map), - (void**)&php_function) == SUCCESS) { - - /* php func prototype: function string user_func($user_params) */ - if(call_user_function(CG(function_table), NULL, *php_function, - retval_ptr, 1, callback_params TSRMLS_CC) == SUCCESS) { - XMLRPC_VALUE xData; - STRUCT_XMLRPC_ERROR err = {0}; - - /* return value should be a string */ - convert_to_string(retval_ptr); - - xData = XMLRPC_IntrospectionCreateDescription(Z_STRVAL_P(retval_ptr), &err); - - if(xData) { - if(!XMLRPC_ServerAddIntrospectionData(server, xData)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s(), improper element structure", Z_STRVAL_PP(php_function)); - } - XMLRPC_CleanupValue(xData); - } - else { - /* could not create description */ - if(err.xml_elem_error.parser_code) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to add introspection data returned from %s()", - err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error, Z_STRVAL_PP(php_function)); - } - else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s()", - Z_STRVAL_PP(php_function)); - } - } - } - else { - /* user func failed */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling user introspection callback: %s()", Z_STRVAL_PP(php_function)); - } - } - else { - break; - } - - zend_hash_move_forward(Z_ARRVAL_P(pData->server->introspection_map)); - } - - /* so we don't call the same callbacks ever again */ - zend_hash_clean(Z_ARRVAL_P(pData->server->introspection_map)); -} - -/* {{{ proto bool xmlrpc_server_register_method(resource server, string method_name, string function) - Register a PHP function to handle method matching method_name */ -PHP_FUNCTION(xmlrpc_server_register_method) -{ - zval **method_key, **method_name, **handle, *method_name_save; - int type; - xmlrpc_server_data* server; - - if (ZEND_NUM_ARGS() != 3 || (zend_get_parameters_ex(3, &handle, &method_key, &method_name) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - server = zend_list_find(Z_LVAL_PP(handle), &type); - - if(type == le_xmlrpc_server) { - /* register with C engine. every method just calls our standard callback, - * and it then dispatches to php as necessary - */ - if(XMLRPC_ServerRegisterMethod(server->server_ptr, Z_STRVAL_PP(method_key), php_xmlrpc_callback)) { - /* save for later use */ - MAKE_STD_ZVAL(method_name_save); - *method_name_save = **method_name; - zval_copy_ctor(method_name_save); - - /* register our php method */ - add_zval(server->method_map, Z_STRVAL_PP(method_key), &method_name_save); - - RETURN_BOOL(1); - } - } - RETURN_BOOL(0); -} -/* }}} */ - - -/* {{{ proto bool xmlrpc_server_register_introspection_callback(resource server, string function) - Register a PHP function to generate documentation */ -PHP_FUNCTION(xmlrpc_server_register_introspection_callback) -{ - zval **method_name, **handle, *method_name_save; - int type; - xmlrpc_server_data* server; - - if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &handle, &method_name) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - server = zend_list_find(Z_LVAL_PP(handle), &type); - - if(type == le_xmlrpc_server) { - /* save for later use */ - MAKE_STD_ZVAL(method_name_save); - *method_name_save = **method_name; - zval_copy_ctor(method_name_save); - - /* register our php method */ - add_zval(server->introspection_map, NULL, &method_name_save); - - RETURN_BOOL(1); - } - RETURN_BOOL(0); -} -/* }}} */ - - -/* this function is itchin for a re-write */ - -/* {{{ proto mixed xmlrpc_server_call_method(resource server, string xml, mixed user_data [, array output_options]) - Parses XML requests and call methods */ -PHP_FUNCTION(xmlrpc_server_call_method) -{ - xmlrpc_callback_data data = {0}; - XMLRPC_REQUEST xRequest; - STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS input_opts; - xmlrpc_server_data* server; - zval **rawxml, **caller_params, **handle, **output_opts = NULL; - int type; - php_output_options out; - int argc =ZEND_NUM_ARGS(); - - if (argc < 3 || argc > 4 || (zend_get_parameters_ex(argc, &handle, &rawxml, &caller_params, &output_opts) != SUCCESS)) { - WRONG_PARAM_COUNT; - } - /* user output options */ - if (argc == 3) { - set_output_options(&out, NULL); - } - else { - set_output_options(&out, *output_opts); - } - - server = zend_list_find(Z_LVAL_PP(handle), &type); - - if(type == le_xmlrpc_server) { - /* HACK: use output encoding for now */ - input_opts.xml_elem_opts.encoding = utf8_get_encoding_id_from_string(out.xmlrpc_out.xml_elem_opts.encoding); - - /* generate an XMLRPC_REQUEST from the raw xml input */ - xRequest = XMLRPC_REQUEST_FromXML(Z_STRVAL_PP(rawxml), Z_STRLEN_PP(rawxml), &input_opts); - - if(xRequest) { - const char* methodname = XMLRPC_RequestGetMethodName(xRequest); - zval **php_function; - XMLRPC_VALUE xAnswer = NULL; - MAKE_STD_ZVAL(data.xmlrpc_method); /* init. very important. spent a frustrating day finding this out. */ - MAKE_STD_ZVAL(data.return_data); - Z_TYPE_P(data.return_data) = IS_NULL; /* in case value is never init'd, we don't dtor to think it is a string or something */ - Z_TYPE_P(data.xmlrpc_method) = IS_NULL; - - if (!methodname) { - methodname = ""; - } - - /* setup some data to pass to the callback function */ - Z_STRVAL_P(data.xmlrpc_method) = estrdup(methodname); - Z_STRLEN_P(data.xmlrpc_method) = strlen(methodname); - Z_TYPE_P(data.xmlrpc_method) = IS_STRING; - data.caller_params = *caller_params; - data.php_executed = 0; - data.server = server; - - /* check if the called method has been previous registered */ - if(zend_hash_find(Z_ARRVAL_P(server->method_map), - Z_STRVAL_P(data.xmlrpc_method), - Z_STRLEN_P(data.xmlrpc_method) + 1, - (void**)&php_function) == SUCCESS) { - - data.php_function = *php_function; - } - - /* We could just call the php method directly ourselves at this point, but we do this - * with a C callback in case the xmlrpc library ever implements some cool usage stats, - * or somesuch. - */ - xAnswer = XMLRPC_ServerCallMethod(server->server_ptr, xRequest, &data); - if(xAnswer && out.b_php_out) { - zval_dtor(data.return_data); - FREE_ZVAL(data.return_data); - data.return_data = XMLRPC_to_PHP(xAnswer); - } else if(data.php_executed && !out.b_php_out) { - xAnswer = PHP_to_XMLRPC(&out, data.return_data); - } - - /* should we return data as xml? */ - if(!out.b_php_out) { - XMLRPC_REQUEST xResponse = XMLRPC_RequestNew(); - if(xResponse) { - char *outBuf = 0; - int buf_len = 0; - - /* automagically determine output serialization type from request type */ - if (out.b_auto_version) { - XMLRPC_REQUEST_OUTPUT_OPTIONS opts = XMLRPC_RequestGetOutputOptions(xRequest); - if (opts) { - out.xmlrpc_out.version = opts->version; - } - } - /* set some required request hoojum */ - XMLRPC_RequestSetOutputOptions(xResponse, &out.xmlrpc_out); - XMLRPC_RequestSetRequestType(xResponse, xmlrpc_request_response); - XMLRPC_RequestSetData(xResponse, xAnswer); - XMLRPC_RequestSetMethodName(xResponse, methodname); - - /* generate xml */ - outBuf = XMLRPC_REQUEST_ToXML(xResponse, &buf_len); - if(outBuf) { - RETVAL_STRINGL(outBuf, buf_len, 1); - free(outBuf); - } - /* cleanup after ourselves. what a sty! */ - XMLRPC_RequestFree(xResponse, 0); - } - } else { /* or as native php types? */ - *return_value = *data.return_data; - zval_copy_ctor(return_value); - } - - /* cleanup after ourselves. what a sty! */ - zval_dtor(data.xmlrpc_method); - FREE_ZVAL(data.xmlrpc_method); - zval_dtor(data.return_data); - FREE_ZVAL(data.return_data); - - if(xAnswer) { - XMLRPC_CleanupValue(xAnswer); - } - - XMLRPC_RequestFree(xRequest, 1); - } - } -} -/* }}} */ - - -/* {{{ proto int xmlrpc_server_add_introspection_data(resource server, array desc) - Adds introspection documentation */ -PHP_FUNCTION(xmlrpc_server_add_introspection_data) -{ - zval **handle, **desc; - int type; - xmlrpc_server_data* server; - - if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &handle, &desc) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - server = zend_list_find(Z_LVAL_PP(handle), &type); - - if (type == le_xmlrpc_server) { - XMLRPC_VALUE xDesc = PHP_to_XMLRPC(NULL, *desc); - if (xDesc) { - int retval = XMLRPC_ServerAddIntrospectionData(server->server_ptr, xDesc); - XMLRPC_CleanupValue(xDesc); - RETURN_LONG(retval); - } - } - RETURN_LONG(0); -} -/* }}} */ - - -/* {{{ proto array xmlrpc_parse_method_descriptions(string xml) - Decodes XML into a list of method descriptions */ -PHP_FUNCTION(xmlrpc_parse_method_descriptions) -{ - zval **arg1, *retval; - - if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &arg1) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(arg1); - - if(return_value_used) { - STRUCT_XMLRPC_ERROR err = {0}; - XMLRPC_VALUE xVal = XMLRPC_IntrospectionCreateDescription(Z_STRVAL_PP(arg1), &err); - if(xVal) { - retval = XMLRPC_to_PHP(xVal); - - if(retval) { - *return_value = *retval; - zval_copy_ctor(return_value); - } - /* dust, sweep, and mop */ - XMLRPC_CleanupValue(xVal); - } else { - /* could not create description */ - if(err.xml_elem_error.parser_code) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to create introspection data", - err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error); - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid xml structure. Unable to create introspection data"); - } - - php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error. no method description created"); - } - } -} -/* }}} */ - - -/************ -* type data * -************/ - -#define XMLRPC_TYPE_COUNT 10 -#define XMLRPC_VECTOR_TYPE_COUNT 4 -#define TYPE_STR_MAP_SIZE (XMLRPC_TYPE_COUNT + XMLRPC_VECTOR_TYPE_COUNT) - -/* return a string matching a given xmlrpc type */ -static const char** get_type_str_mapping(void) -{ - static const char* str_mapping[TYPE_STR_MAP_SIZE]; - static int first = 1; - if (first) { - /* warning. do not add/delete without changing size define */ - str_mapping[xmlrpc_none] = "none"; - str_mapping[xmlrpc_empty] = "empty"; - str_mapping[xmlrpc_nil] = "nil"; - str_mapping[xmlrpc_base64] = "base64"; - str_mapping[xmlrpc_boolean] = "boolean"; - str_mapping[xmlrpc_datetime] = "datetime"; - str_mapping[xmlrpc_double] = "double"; - str_mapping[xmlrpc_int] = "int"; - str_mapping[xmlrpc_string] = "string"; - str_mapping[xmlrpc_vector] = "vector"; - str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_none] = "none"; - str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_array] = "array"; - str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_mixed] = "mixed"; - str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_struct] = "struct"; - first = 0; - } - return (const char**)str_mapping; -} - -/* map an xmlrpc type to a string */ -const char* xmlrpc_type_as_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype) -{ - const char** str_mapping = get_type_str_mapping(); - - if (vtype == xmlrpc_vector_none) { - return str_mapping[type]; - } else { - return str_mapping[XMLRPC_TYPE_COUNT + vtype]; - } -} - -/* map a string to an xmlrpc type */ -XMLRPC_VALUE_TYPE xmlrpc_str_as_type(const char* str) -{ - const char** str_mapping = get_type_str_mapping(); - int i; - - if (str) { - for (i = 0; i < XMLRPC_TYPE_COUNT; i++) { - if (!strcmp(str_mapping[i], str)) { - return (XMLRPC_VALUE_TYPE) i; - } - } - } - return xmlrpc_none; -} - -/* map a string to an xmlrpc vector type */ -XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str) -{ - const char** str_mapping = get_type_str_mapping(); - int i; - - if (str) { - for (i = XMLRPC_TYPE_COUNT; i < TYPE_STR_MAP_SIZE; i++) { - if (!strcmp(str_mapping[i], str)) { - return (XMLRPC_VECTOR_TYPE) (i - XMLRPC_TYPE_COUNT); - } - } - } - return xmlrpc_none; -} - - -/* set a given value to a particular type. - * note: this only works on strings, and only for date and base64, - * which do not have native php types. black magic lies herein. - */ -int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE newtype) -{ - int bSuccess = FAILURE; - TSRMLS_FETCH(); - - /* we only really care about strings because they can represent - * base64 and datetime. all other types have corresponding php types - */ - if (Z_TYPE_P(value) == IS_STRING) { - if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) { - const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none); - zval* type; - - MAKE_STD_ZVAL(type); - - Z_TYPE_P(type) = IS_STRING; - Z_STRVAL_P(type) = estrdup(typestr); - Z_STRLEN_P(type) = strlen(typestr); - - if(newtype == xmlrpc_datetime) { - XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val); - if(v) { - time_t timestamp = XMLRPC_GetValueDateTime(v); - if(timestamp) { - pval* ztimestamp; - - MAKE_STD_ZVAL(ztimestamp); - - ztimestamp->type = IS_LONG; - ztimestamp->value.lval = timestamp; - - convert_to_object(value); - if(SUCCESS == zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) { - bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL); - } - } - XMLRPC_CleanupValue(v); - } - } - else { - convert_to_object(value); - bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL); - } - } - } - - return bSuccess; -} - -/* return xmlrpc type of a php value */ -XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(php_output_options* out, zval* value, zval** newvalue) -{ - XMLRPC_VALUE_TYPE type = xmlrpc_none; - TSRMLS_FETCH(); - XMLRPCLS_FETCH(); - - if (value) { - switch (Z_TYPE_P(value)) { - case IS_NULL: - if (XMLRPCG(allow_null) || (out && out->b_allow_null)) { - type = xmlrpc_nil; - } else { - type = xmlrpc_string; - } - break; -#ifndef BOOL_AS_LONG - - /* Right thing to do, but it breaks some legacy code. */ - case IS_BOOL: - type = xmlrpc_boolean; - break; -#else - case IS_BOOL: -#endif - case IS_LONG: - case IS_RESOURCE: - type = xmlrpc_int; - break; - case IS_DOUBLE: - type = xmlrpc_double; - break; - case IS_CONSTANT: - type = xmlrpc_string; - break; - case IS_STRING: - type = xmlrpc_string; - break; - case IS_ARRAY: -/* jan. 2 2015 - see note in file header */ -#ifdef IS_CONSTANT_ARRAY - case IS_CONSTANT_ARRAY: -#endif - type = xmlrpc_vector; - break; - case IS_OBJECT: - { - zval** attr; - type = xmlrpc_vector; - - if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) { - if (Z_TYPE_PP(attr) == IS_STRING) { - type = xmlrpc_str_as_type(Z_STRVAL_PP(attr)); - } - } - break; - } - } - - /* if requested, return an unmolested (magic removed) copy of the value */ - if (newvalue) { - zval** val; - - if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) { - if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR), (void**) &val) == SUCCESS) { - *newvalue = *val; - } - } else { - *newvalue = value; - } - } - } - - return type; -} - - -/* {{{ proto bool xmlrpc_set_type(string value, string type) - Sets xmlrpc type, base64 or datetime or nil, for a PHP string value */ -PHP_FUNCTION(xmlrpc_set_type) -{ - zval **arg, **type; - XMLRPC_VALUE_TYPE vtype; - - if (ZEND_NUM_ARGS() != 2 || (zend_get_parameters_ex(2, &arg, &type) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - convert_to_string_ex(type); - vtype = xmlrpc_str_as_type(Z_STRVAL_PP(type)); - if (vtype != xmlrpc_none) { - if (set_zval_xmlrpc_type(*arg, vtype) == SUCCESS) { - RETURN_TRUE; - } - } else { - zend_error(E_WARNING,"invalid type '%s' passed to xmlrpc_set_type()", Z_STRVAL_PP(type)); - } - RETURN_FALSE; -} -/* }}} */ - -/* {{{ proto string xmlrpc_get_type(mixed value) - Gets xmlrpc type for a PHP value. Especially useful for base64 and datetime strings */ -PHP_FUNCTION(xmlrpc_get_type) -{ - zval **arg; - XMLRPC_VALUE_TYPE type; - XMLRPC_VECTOR_TYPE vtype = xmlrpc_vector_none; - - if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &arg) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - type = get_zval_xmlrpc_type(NULL, *arg, 0); - if (type == xmlrpc_vector) { - vtype = determine_vector_type(Z_ARRVAL_PP(arg)); - } - - RETURN_STRING((char*) xmlrpc_type_as_str(type, vtype), 1); -} -/* }}} */ - -/* {{{ proto bool xmlrpc_is_fault(array) - Determines if an array value represents an XMLRPC fault. */ -PHP_FUNCTION(xmlrpc_is_fault) -{ - zval **arg, **val; - - if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &arg) == FAILURE)) { - WRONG_PARAM_COUNT; - } - - if (Z_TYPE_PP(arg) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array argument expected"); - } else { - /* The "correct" way to do this would be to call the xmlrpc - * library XMLRPC_ValueIsFault() func. However, doing that - * would require us to create an xmlrpc value from the php - * array, which is rather expensive, especially if it was - * a big array. Thus, we resort to this not so clever hackery. - */ - if (zend_hash_find(Z_ARRVAL_PP(arg), FAULT_CODE, FAULT_CODE_LEN + 1, (void**) &val) == SUCCESS && - zend_hash_find(Z_ARRVAL_PP(arg), FAULT_STRING, FAULT_STRING_LEN + 1, (void**) &val) == SUCCESS) { - RETURN_TRUE; - } - } - - RETURN_FALSE; -} -/* }}} */ - - - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - diff --git a/php/xmlrpc/xmlrpc.dsp b/php/xmlrpc/xmlrpc.dsp deleted file mode 100644 index 8c455d3..0000000 --- a/php/xmlrpc/xmlrpc.dsp +++ /dev/null @@ -1,211 +0,0 @@ -# Microsoft Developer Studio Project File - Name="xmlrpc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=xmlrpc - Win32 Debug_TS -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "xmlrpc.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "xmlrpc.mak" CFG="xmlrpc - Win32 Debug_TS" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "xmlrpc - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "xmlrpc - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "xmlrpc - Win32 Debug_TS" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug_TS" -# PROP BASE Intermediate_Dir "Debug_TS" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_TS" -# PROP Intermediate_Dir "Debug_TS" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLRPC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "libxmlrpc" /I "..\..\bundle\expat" /D HAVE_XMLRPC=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=1 /D ZTS=1 /D COMPILE_DL_XMLRPC=1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLRPC_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1009 /d "_DEBUG" -# ADD RSC /l 0x1009 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 php5ts_debug.lib expat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_xmlrpc.dll" /pdbtype:sept /libpath:"..\..\Debug_TS" - -!ELSEIF "$(CFG)" == "xmlrpc - Win32 Release_TS" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release_TS" -# PROP BASE Intermediate_Dir "Release_TS" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_TS" -# PROP Intermediate_Dir "Release_TS" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLRPC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "libxmlrpc" /I "..\..\bundle\expat" /D HAVE_XMLRPC=1 /D "ZEND_WIN32" /D ZEND_DEBUG=0 /D "PHP_WIN32" /D ZTS=1 /D COMPILE_DL_XMLRPC=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XMLRPC_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x1009 /d "NDEBUG" -# ADD RSC /l 0x1009 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 php5ts.lib expat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_xmlrpc.dll" /libpath:"..\..\Release_TS" - -!ENDIF - -# Begin Target - -# Name "xmlrpc - Win32 Debug_TS" -# Name "xmlrpc - Win32 Release_TS" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=".\xmlrpc-epi-php.c" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\php_xmlrpc.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# Begin Group "libxmlrpc" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\libxmlrpc\base64.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\base64.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\encodings.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\encodings.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\queue.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\queue.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\simplestring.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\simplestring.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\system_methods.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\system_methods_private.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_element.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_element.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_dandarpc.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_dandarpc.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_soap.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_soap.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_xmlrpc.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xml_to_xmlrpc.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc_introspection.c -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc_introspection.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc_introspection_private.h -# End Source File -# Begin Source File - -SOURCE=.\libxmlrpc\xmlrpc_private.h -# End Source File -# End Group -# End Target -# End Project diff --git a/plcapi.spec b/plcapi.spec index 670a47f..8846023 100644 --- a/plcapi.spec +++ b/plcapi.spec @@ -52,19 +52,21 @@ Requires: memcached python-memcached ### avoid having yum complain about updates, as stuff is moving around # plc.d/api Conflicts: MyPLC <= 4.3 +# xmlrpc +Requires: php-xmlrpc # We use psycopg2 # # but we don't need to rebuild it as we depend on distro's packages - baris # BuildRequires: postgresql-devel -# Standard xmlrpc.so that ships with PHP does not marshal NULL -# for building the wsdl interface we used to require PyXML -# but this has gone with f20 so turning this off for now -BuildRequires: php-devel -#BuildRequires: python-simplejson -Obsoletes: php-xmlrpc -Provides: php-xmlrpc +### # Standard xmlrpc.so that ships with PHP does not marshal NULL +### # for building the wsdl interface we used to require PyXML +### # but this has gone with f20 so turning this off for now +### BuildRequires: php-devel +### #BuildRequires: python-simplejson +### Obsoletes: php-xmlrpc +### Provides: php-xmlrpc # PostgreSQL and SOAPpy are necessary to run the API server, but not # plcsh. Since the only supported method of running the server is via @@ -99,11 +101,11 @@ rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/%{_bindir} ln -s %{_datadir}/plc_api/plcsh $RPM_BUILD_ROOT/%{_bindir}/plcsh -mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/php.d -cat > $RPM_BUILD_ROOT/%{_sysconfdir}/php.d/xmlrpc.ini < $RPM_BUILD_ROOT/%{_sysconfdir}/php.d/xmlrpc.ini <