diff --git a/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake b/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake deleted file mode 100644 index 1e1006b35c..0000000000 --- a/Utilities/cmxmlrpc/CMake/TryCompileFromSource.cmake +++ /dev/null @@ -1,46 +0,0 @@ -MACRO(TRY_COMPILE_FROM_SOURCE SOURCE VAR) - IF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(TRY_COMPILE_FROM_SOURCE_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ENDIF(CMAKE_REQUIRED_LIBRARIES) - SET(src "") - FOREACH(def ${EXTRA_DEFINES}) - SET(src "${src}#define ${def} 1\n") - ENDFOREACH(def) - FOREACH(inc ${HEADER_INCLUDES}) - SET(src "${src}#include <${inc}>\n") - ENDFOREACH(inc) - - SET(src "${src}\nint main() { ${SOURCE} ; return 0; }") - FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src2.c" - "${src}\n") - EXEC_PROGRAM("${CMAKE_COMMAND}" - "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp" - ARGS -E copy src2.c src.c) - MESSAGE(STATUS "Performing Test ${VAR}") - TRY_COMPILE(${VAR} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c - CMAKE_FLAGS - "${TRY_COMPILE_FROM_SOURCE_ADD_LIBRARIES}" - OUTPUT_VARIABLE OUTPUT) - IF(${VAR}) - SET(${VAR} 1 CACHE INTERNAL "Test ${FUNCTION}") - MESSAGE(STATUS "Performing Test ${VAR} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${src}\n") - ELSE(${VAR}) - MESSAGE(STATUS "Performing Test ${VAR} - Failed") - SET(${VAR} "" CACHE INTERNAL "Test ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${src}\n") - ENDIF(${VAR}) - ENDIF("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN") -ENDMACRO(TRY_COMPILE_FROM_SOURCE) diff --git a/Utilities/cmxmlrpc/CMakeLists.txt b/Utilities/cmxmlrpc/CMakeLists.txt deleted file mode 100644 index e3f42c8397..0000000000 --- a/Utilities/cmxmlrpc/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ -PROJECT(XMLRPC) - -INCLUDE_REGULAR_EXPRESSION("^.*$") - -# Disable warnings on Borland to avoid changing 3rd party code. -IF(BORLAND) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-") -ENDIF(BORLAND) - -# Include all the necessary files for macros -SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") - -# Check if header file exists and add it to the list. -SET(CURRENT_INCLUDES) -INCLUDE (CheckIncludeFiles) -MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) - CHECK_INCLUDE_FILES("${CURRENT_INCLUDES};${FILE}" ${VARIABLE}) - IF(${VARIABLE}) - SET(CURRENT_INCLUDES ${CURRENT_INCLUDES} ${FILE}) - ENDIF(${VARIABLE}) -ENDMACRO(CHECK_INCLUDE_FILE_CONCAT) - -CHECK_INCLUDE_FILE_CONCAT("stdio.h" HAVE_STDIO_H) -CHECK_INCLUDE_FILE_CONCAT("stdarg.h" HAVE_STDARG_H) -CHECK_INCLUDE_FILE_CONCAT("sys/filio.h" HAVE_SYS_FILIO_H) -CHECK_INCLUDE_FILE_CONCAT("sys/ioctl.h" HAVE_SYS_IOCTL_H) -CHECK_INCLUDE_FILE_CONCAT("wchar.h" HAVE_WCHAR_H) - -IF(HAVE_WCHAR_H) - OPTION(HAVE_UNICODE_WCHAR "Enable Unicode Support" YES) - MARK_AS_ADVANCED(HAVE_UNICODE_WCHAR) -ELSE(HAVE_WCHAR_H) - SET(HAVE_UNICODE_WCHAR 0) -ENDIF(HAVE_WCHAR_H) - -INCLUDE (CheckSymbolExists) -CHECK_SYMBOL_EXISTS(asprintf "${CURRENT_INCLUDES}" HAVE_ASPRINTF) -CHECK_SYMBOL_EXISTS(setgroups "${CURRENT_INCLUDES}" HAVE_SETGROUPS) - -INCLUDE (CheckTypeSize) -CHECK_TYPE_SIZE(size_t SIZEOF_SIZE_T) - -INCLUDE (TryCompileFromSource) -SET(HEADER_INCLUDES "${CURRENT_INCLUDES}") -TRY_COMPILE_FROM_SOURCE("va_list list1, list2; list1 = list2" - VA_LIST_ISNOT_ARRAY_DEFINE) -TRY_COMPILE_FROM_SOURCE("va_list list1, list2; va_copy(list1, list2);" - HAS_VA_COPY) -SET(VA_LIST_IS_ARRAY_DEFINE 0) -IF(NOT VA_LIST_ISNOT_ARRAY_DEFINE) - SET(VA_LIST_IS_ARRAY_DEFINE 1) -ENDIF(NOT VA_LIST_ISNOT_ARRAY_DEFINE) -TRY_COMPILE_FROM_SOURCE("int x __attribute__((__unused__))" - ATTR_UNUSED_VAR) -SET(ATTR_UNUSED) -IF(ATTR_UNUSED_VAR) - SET(ATTR_UNUSED "__attribute__((__unused__))") -ENDIF(ATTR_UNUSED_VAR) - -SET(HAVE_LIBWWW_SSL) -SET(DIRECTORY_SEPARATOR "/") - -SET(HAVE_PTHREADS 0) -IF(CMAKE_BUILD_XMLRPC_WITH_THREADS) - FIND_PACKAGE(Threads) - IF(WIN32 OR CMAKE_USE_PTHREADS_INIT) - SET(HAVE_PTHREADS 1) - ENDIF(WIN32 OR CMAKE_USE_PTHREADS_INIT) -ENDIF(CMAKE_BUILD_XMLRPC_WITH_THREADS) - -INCLUDE_DIRECTORIES( - "${CMAKE_CURRENT_SOURCE_DIR}" - "${CMAKE_CURRENT_BINARY_DIR}" - ${CMAKE_EXPAT_INCLUDES} - ${CMAKE_CURL_INCLUDES} - ) - -CONFIGURE_FILE( - "${CMAKE_CURRENT_SOURCE_DIR}/xmlrpc_config.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/xmlrpc_config.h" - ) -CONFIGURE_FILE( - "${CMAKE_CURRENT_SOURCE_DIR}/xmlrpc_amconfig.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/xmlrpc_amconfig.h" - ) - -SET(xmlrpc_SRCS - #XmlRpcCpp.cpp - xmlrpc_array.c - xmlrpc_authcookie.c - xmlrpc_base64.c - xmlrpc_client.c - xmlrpc_data.c - xmlrpc_expat.c - xmlrpc_parse.c - xmlrpc_registry.c - xmlrpc_serialize.c - xmlrpc_curl_transport.c - #xmlrpc_server_abyss.c - xmlrpc_struct.c - xmlrpc_strutil.c - xmlrpc_support.c - casprintf.c - ) -IF(HAVE_UNICODE_WCHAR) - SET(xmlrpc_SRCS - ${xmlrpc_SRCS} - xmlrpc_utf8.c - ) -ENDIF(HAVE_UNICODE_WCHAR) -IF(WIN32) - SET(xmlrpc_SRCS ${xmlrpc_SRCS} - win32_pthreads.c - ) -ENDIF(WIN32) - -ADD_LIBRARY(cmXMLRPC ${xmlrpc_SRCS}) -TARGET_LINK_LIBRARIES(cmXMLRPC ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_CURL_LIBRARIES}) -IF(HAVE_PTHREADS) - TARGET_LINK_LIBRARIES(cmXMLRPC ${CMAKE_THREAD_LIBS_INIT}) -ENDIF(HAVE_PTHREADS) - -ADD_EXECUTABLE(xrtest synch_client.c) -TARGET_LINK_LIBRARIES(xrtest cmXMLRPC ${CMAKE_DL_LIBS}) - -# comment out test since it doesn pass and Andy doesn;t seem to be fixing it, -# for now assume that XMLRPC is not production quality code - Ken -# ADD_TEST(Test-XMLRPC ${EXECUTABLE_OUTPUT_PATH}/xrtest) diff --git a/Utilities/cmxmlrpc/XmlRpcCpp.cpp b/Utilities/cmxmlrpc/XmlRpcCpp.cpp deleted file mode 100644 index 119b6951d2..0000000000 --- a/Utilities/cmxmlrpc/XmlRpcCpp.cpp +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (C) 2001 by Eric Kidd. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. - - -#include "XmlRpcCpp.h" - - -//========================================================================= -// XmlRpcFault Methods -//========================================================================= - -XmlRpcFault::XmlRpcFault (const XmlRpcFault &fault) { - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, - fault.mFault.fault_code, - fault.mFault.fault_string); -} - -XmlRpcFault::XmlRpcFault (const int faultCode, const string faultString) { - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, faultCode, - const_cast(faultString.c_str())); -} - -XmlRpcFault::XmlRpcFault (const xmlrpc_env *env) { - if (!env->fault_string) - throw XmlRpcFault(XMLRPC_INTERNAL_ERROR, - "Tried to create empty fault"); - xmlrpc_env_init(&mFault); - xmlrpc_env_set_fault(&mFault, env->fault_code, - const_cast(env->fault_string)); -} - -XmlRpcFault::~XmlRpcFault (void) { - xmlrpc_env_clean(&mFault); -} - -string XmlRpcFault::getFaultString (void) const { - XMLRPC_ASSERT(mFault.fault_occurred); - return string(mFault.fault_string); -} - - -//========================================================================= -// XmlRpcEnv Methods -//========================================================================= - -XmlRpcEnv::XmlRpcEnv (const XmlRpcEnv &env) { - xmlrpc_env_init(&mEnv); - if (env.hasFaultOccurred()) - xmlrpc_env_set_fault(&mEnv, - env.mEnv.fault_code, - env.mEnv.fault_string); -} - -XmlRpcFault XmlRpcEnv::getFault (void) const { - return XmlRpcFault(&mEnv); -} - -void XmlRpcEnv::throwMe (void) const { - throw XmlRpcFault(&mEnv); -} - - -//========================================================================= -// XmlRpcValue Methods -//========================================================================= - -// If the user doesn't tell us what kind of value to create, use -// a false boolean value as the default. -XmlRpcValue::XmlRpcValue (void) { - XmlRpcEnv env; - mValue = xmlrpc_build_value(env, "b", (xmlrpc_bool) 0); - env.throwIfFaultOccurred(); -} - -XmlRpcValue XmlRpcValue::makeInt (const XmlRpcValue::int32 i) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "i", i); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeBool (const bool b) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "b", (xmlrpc_bool) b); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeDouble (const double d) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "d", d); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeDateTime (const string& dateTime) { - XmlRpcEnv env; - xmlrpc_value *value; - const char *data = dateTime.c_str(); // Make sure we're not using wchar_t. - value = xmlrpc_build_value(env, "8", data); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const string& str) { - XmlRpcEnv env; - const char *data = str.data(); // Make sure we're not using wchar_t. - size_t size = str.size(); - xmlrpc_value *value = xmlrpc_build_value(env, "s#", data, size); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const char *const str) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "s", str); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeString (const char *const str, size_t len) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "s#", str, len); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeArray (void) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "()"); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeStruct (void) { - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_struct_new(env); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue XmlRpcValue::makeBase64 (const unsigned char *const data, - size_t len) -{ - XmlRpcEnv env; - xmlrpc_value *value = xmlrpc_build_value(env, "6", data, len); - env.throwIfFaultOccurred(); - return XmlRpcValue(value, CONSUME_REFERENCE); -} - -XmlRpcValue::int32 XmlRpcValue::getInt (void) const { - XmlRpcEnv env; - XmlRpcValue::int32 result; - xmlrpc_parse_value(env, mValue, "i", &result); - env.throwIfFaultOccurred(); - return result; -} - -bool XmlRpcValue::getBool (void) const { - XmlRpcEnv env; - xmlrpc_bool result; - xmlrpc_parse_value(env, mValue, "b", &result); - env.throwIfFaultOccurred(); - return result; -} - -double XmlRpcValue::getDouble (void) const { - XmlRpcEnv env; - double result; - xmlrpc_parse_value(env, mValue, "d", &result); - env.throwIfFaultOccurred(); - return result; -} - -string XmlRpcValue::getRawDateTime (void) const { - XmlRpcEnv env; - char *result; - xmlrpc_parse_value(env, mValue, "8", &result); - env.throwIfFaultOccurred(); - return string(result); -} - -string XmlRpcValue::getString (void) const { - XmlRpcEnv env; - char *result; - size_t result_len; - xmlrpc_parse_value(env, mValue, "s#", &result, &result_len); - env.throwIfFaultOccurred(); - return string(result, result_len); - -} - -XmlRpcValue XmlRpcValue::getArray (void) const { - XmlRpcEnv env; - xmlrpc_value *result; - xmlrpc_parse_value(env, mValue, "A", &result); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -XmlRpcValue XmlRpcValue::getStruct (void) const { - XmlRpcEnv env; - xmlrpc_value *result; - xmlrpc_parse_value(env, mValue, "S", &result); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -void XmlRpcValue::getBase64 (const unsigned char *& out_data, - size_t& out_len) const -{ - XmlRpcEnv env; - xmlrpc_parse_value(env, mValue, "6", &out_data, &out_len); - env.throwIfFaultOccurred(); -} - -size_t XmlRpcValue::arraySize (void) const { - XmlRpcEnv env; - size_t result = xmlrpc_array_size(env, mValue); - env.throwIfFaultOccurred(); - return result; -} - -void XmlRpcValue::arrayAppendItem (const XmlRpcValue& value) { - XmlRpcEnv env; - xmlrpc_array_append_item(env, mValue, value.borrowReference()); - env.throwIfFaultOccurred(); -} - -XmlRpcValue XmlRpcValue::arrayGetItem (int index) const { - XmlRpcEnv env; - xmlrpc_value *result = xmlrpc_array_get_item(env, mValue, index); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -size_t XmlRpcValue::structSize (void) const { - XmlRpcEnv env; - size_t result = xmlrpc_struct_size(env, mValue); - env.throwIfFaultOccurred(); - return result; -} - -bool XmlRpcValue::structHasKey (const string& key) const { - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - bool result = xmlrpc_struct_has_key_n(env, mValue, - const_cast(keystr), keylen); - env.throwIfFaultOccurred(); - return result; -} - -XmlRpcValue XmlRpcValue::structGetValue (const string& key) const { - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - xmlrpc_value *result = - xmlrpc_struct_get_value_n(env, mValue, - const_cast(keystr), keylen); - env.throwIfFaultOccurred(); - return XmlRpcValue(result); -} - -void XmlRpcValue::structSetValue (const string& key, const XmlRpcValue& value) -{ - XmlRpcEnv env; - const char *keystr = key.data(); - size_t keylen = key.size(); - xmlrpc_struct_set_value_n(env, mValue, (char*) keystr, keylen, - value.borrowReference()); - env.throwIfFaultOccurred(); -} - -void XmlRpcValue::structGetKeyAndValue (const int index, - string& out_key, - XmlRpcValue& out_value) const -{ - XmlRpcEnv env; - - xmlrpc_value *key, *value; - xmlrpc_struct_get_key_and_value(env, mValue, index, &key, &value); - env.throwIfFaultOccurred(); - - out_key = XmlRpcValue(key).getString(); - out_value = XmlRpcValue(value); -} - -XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, - xmlrpc_method method, - void *data) -{ - XmlRpcEnv env; - - xmlrpc_registry_add_method (env, mRegistry, NULL, - name.c_str (), - method, data); - - env.throwIfFaultOccurred (); - return (*this); -} - -XmlRpcGenSrv& XmlRpcGenSrv::addMethod (const string& name, - xmlrpc_method method, - void* data, - const string& signature, - const string& help) -{ - XmlRpcEnv env; - - xmlrpc_registry_add_method_w_doc (env, mRegistry, NULL, - name.c_str (), - method, data, - signature.c_str (), - help.c_str ()); - - env.throwIfFaultOccurred (); - return (*this); -} - -xmlrpc_mem_block* XmlRpcGenSrv::alloc (XmlRpcEnv& env, const string& body) const -{ - xmlrpc_mem_block* result = NULL; - char* contents; - - result = xmlrpc_mem_block_new (env, body.length ()); - env.throwIfFaultOccurred (); - - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); - - memcpy (contents, body.c_str (), body.length ()); - return result; -} - -string XmlRpcGenSrv::handle (const string& body) const -{ - XmlRpcEnv env; - string result; - xmlrpc_mem_block* input = NULL, * output = NULL; - char* input_data, * output_data; - size_t input_size, output_size; - - if (body.length () > xmlrpc_limit_get (XMLRPC_XML_SIZE_LIMIT_ID)) - throw XmlRpcFault (XMLRPC_LIMIT_EXCEEDED_ERROR, "XML-RPC request too large"); - - input = alloc (env, body); - input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); - input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); - - output = xmlrpc_registry_process_call (env, mRegistry, NULL, - input_data, input_size); - - if (output) - { - output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); - output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - - result.assign (output_data, output_size); - xmlrpc_mem_block_free (output); - } - - xmlrpc_mem_block_free (input); - if (!result.length ()) - throw XmlRpcFault (env); - - return result; -} diff --git a/Utilities/cmxmlrpc/XmlRpcCpp.h b/Utilities/cmxmlrpc/XmlRpcCpp.h deleted file mode 100644 index 05a3ad017e..0000000000 --- a/Utilities/cmxmlrpc/XmlRpcCpp.h +++ /dev/null @@ -1,428 +0,0 @@ -// -*- C++ -*- <-- an Emacs control - -// Copyright information is at the bottom of the file. - -//========================================================================= -// XML-RPC C++ API -//========================================================================= - - -#ifndef _XMLRPCCPP_H_ -#define _XMLRPCCPP_H_ 1 - -// The C++ standard says we should either include (which gets -// us the wrong header), or say 'using namespace std;' (which doesn't -// work with our version of g++). So this header name is technically wrong. -// Tell me what your compiler does; I can provide some autoconf magic to the -// Right Thing on most platforms. -// -// 2004.12.22 Bryan: This looks like a problem with whatever g++ he was -// using, so if anything, the special case should be for that. In any case, -// we've already added using namespace std to other files, without knowing -// there was an issue, so I'm just going to do the "using namespace" -// unconditionally and see who complains. If there are complaints, we can -// improve the documentation here. -// -// Formerly, the "using namespace std" was under -// "#if defined(__GNUC__) && (__GNUC__ >= 3)". - - -#include - -using namespace std; - -#include -#include -#include -#include - -#define XMLRPC_NO_ASSIGNMENT \ - XMLRPC_FATAL_ERROR("Assignment operator not available"); return *this; - - -//========================================================================= -// XmlRpcFault -//========================================================================= -// A C++ exception class representing an XML-RPC fault. - -class XmlRpcFault { - -private: - xmlrpc_env mFault; - - XmlRpcFault& operator= (const XmlRpcFault& f) - { (void) f; XMLRPC_NO_ASSIGNMENT } - -public: - XmlRpcFault (const XmlRpcFault &fault); - XmlRpcFault (const int faultCode, const string faultString); - XmlRpcFault (const xmlrpc_env *env); - ~XmlRpcFault (void); - - int getFaultCode (void) const; - string getFaultString (void) const; - xmlrpc_env *getFaultEnv (void); -}; - -inline int XmlRpcFault::getFaultCode (void) const { - return mFault.fault_code; -} - -inline xmlrpc_env *XmlRpcFault::getFaultEnv (void) { - return &mFault; -} - - -//========================================================================= -// XmlRpcEnv -//========================================================================= -// This class can be used to wrap xmlrpc_env object. Use it as follows: -// -// XmlRpcEnv env; -// xmlrpc_parse_value(env, v, "(i)", &i); -// env.throwIfFaultOccurred(); - -class XmlRpcEnv { - -private: - xmlrpc_env mEnv; - - void throwMe (void) const; - XmlRpcEnv& operator= (const XmlRpcEnv& e) - { (void) e; XMLRPC_NO_ASSIGNMENT } - -public: - XmlRpcEnv (const XmlRpcEnv &env); - XmlRpcEnv (void) { xmlrpc_env_init(&mEnv); } - ~XmlRpcEnv (void) { xmlrpc_env_clean(&mEnv); } - - bool faultOccurred (void) const { return mEnv.fault_occurred; }; - bool hasFaultOccurred (void) const { return faultOccurred(); }; - /* hasFaultOccurred() is for backward compatibility. - faultOccurred() is a superior name for this. - */ - XmlRpcFault getFault (void) const; - - void throwIfFaultOccurred (void) const; - - operator xmlrpc_env * (void) { return &mEnv; } -}; - -inline void XmlRpcEnv::throwIfFaultOccurred (void) const { - if (faultOccurred()) - throwMe(); -} - - -//========================================================================= -// XmlRpcValue -//========================================================================= -// An object in this class is an XML-RPC value. -// -// We have a complex structure to allow C code mixed in with C++ code -// which uses this class to refer to the same XML-RPC value object. -// This is especially important because there aren't proper C++ facilities -// for much of Xmlrpc-c; you have to use the C facilities even if you'd -// rather use proper C++. -// -// The XmlRpcValue object internally represents the value as an -// xmlrpc_value. It hold one reference to the xmlrpc_value. Users -// of XmlRpcValue never see that xmlrpc_value, but C code can. the -// C code might create the xmlrpc_value and then bind it to an XmlRpcValue, -// or it might get the xmlrpc_value handle from the XmlRpcValue. Finally, -// C code can simply use the XmlRpcValue where an xmlrpc_value handle is -// required and it gets converted automatically. -// -// So reference counting for the xmlrpc_value is quite a nightmare. - -class XmlRpcValue { - -private: - xmlrpc_value *mValue; - -public: - enum ReferenceBehavior { - MAKE_REFERENCE, - CONSUME_REFERENCE - }; - - typedef xmlrpc_int32 int32; - - XmlRpcValue (void); - XmlRpcValue (xmlrpc_value *value, - ReferenceBehavior behavior = MAKE_REFERENCE); - XmlRpcValue (const XmlRpcValue& value); - ~XmlRpcValue (void); - - XmlRpcValue& operator= (const XmlRpcValue& value); - - // Accessing the value's type (think of this as lightweight RTTI). - xmlrpc_type getType(void) const; - - // We don't supply an automatic conversion operator--you need to say - // whether you want to make or borrow this object's reference. - // XXX - Is it really OK for these to be const? - xmlrpc_value *makeReference (void) const; - xmlrpc_value *borrowReference (void) const; - - // Some static "constructor" functions. - static XmlRpcValue makeInt (const XmlRpcValue::int32 i); - static XmlRpcValue makeBool (const bool b); - static XmlRpcValue makeDouble (const double d); - static XmlRpcValue makeDateTime (const string& dateTime); - static XmlRpcValue makeString (const string& str); - static XmlRpcValue makeString (const char *const str); - static XmlRpcValue makeString (const char *const str, size_t len); - static XmlRpcValue makeArray (void); - static XmlRpcValue makeStruct (void); - static XmlRpcValue makeBase64 (const unsigned char *const data, - size_t len); - /* - // An interface to xmlrpc_build_value. - static XmlRpcValue buildValue (const char *const format, ...); - */ - - // Some functions to get the underlying data. - // These will throw an XmlRpcFault if the data is the wrong type. - XmlRpcValue::int32 getInt (void) const; - bool getBool (void) const; - double getDouble (void) const; - string getRawDateTime (void) const; - string getString (void) const; - XmlRpcValue getArray (void) const; - XmlRpcValue getStruct (void) const; - - // This returns an internal pointer which will become invalid when - // all references to the underlying value are destroyed. - void getBase64 (const unsigned char *& out_data, - size_t& out_len) const; - - /* - // An interface to xmlrpc_parse_value. - void parseValue (const char *const format, ...); - */ - - // Array functions. These will throw an XmlRpcFault if the value - // isn't an array. - size_t arraySize (void) const; - void arrayAppendItem (const XmlRpcValue& value); - XmlRpcValue arrayGetItem (int index) const; - - // Struct functions. These will throw an XmlRpcFault if the value - // isn't a struct. - size_t structSize (void) const; - bool structHasKey (const string& key) const; - XmlRpcValue structGetValue (const string& key) const; - void structSetValue (const string& key, const XmlRpcValue& value); - void structGetKeyAndValue (const int index, - string& out_key, - XmlRpcValue& out_value) const; -}; - -inline XmlRpcValue::XmlRpcValue (xmlrpc_value *value, - ReferenceBehavior behavior) -{ - mValue = value; - - if (behavior == MAKE_REFERENCE) - xmlrpc_INCREF(value); -} - -inline XmlRpcValue::XmlRpcValue (const XmlRpcValue& value) { - mValue = value.mValue; - xmlrpc_INCREF(mValue); -} - -inline XmlRpcValue::~XmlRpcValue (void) { - xmlrpc_DECREF(mValue); -} - -inline XmlRpcValue& XmlRpcValue::operator= (const XmlRpcValue& value) { - // Must increment before we decrement, in case of assignment to self. - xmlrpc_INCREF(value.mValue); - xmlrpc_DECREF(mValue); - mValue = value.mValue; - return *this; -} - -inline xmlrpc_type XmlRpcValue::getType (void) const { - return xmlrpc_value_type(mValue); -} - -inline xmlrpc_value *XmlRpcValue::makeReference (void) const { - xmlrpc_INCREF(mValue); - return mValue; -} - -inline xmlrpc_value *XmlRpcValue::borrowReference (void) const { - return mValue; -} - - -//========================================================================= -// XmlRpcClient -//========================================================================= - -class XmlRpcClient { - -private: - string mServerUrl; - -public: - static void Initialize (string appname, string appversion); - static void Terminate (void); - - XmlRpcClient (const string& server_url) : mServerUrl(server_url) {} - ~XmlRpcClient (void) {} - - XmlRpcClient (const XmlRpcClient& client); - XmlRpcClient& operator= (const XmlRpcClient& client); - - XmlRpcValue call (string method_name, XmlRpcValue param_array); - void call_asynch (string method_name, - XmlRpcValue param_array, - xmlrpc_response_handler callback, - void* user_data); - void event_loop_asynch (unsigned long milliseconds); -}; - -inline void XmlRpcClient::call_asynch(string method_name, - XmlRpcValue param_array, - xmlrpc_response_handler callback, - void* user_data) -{ - xmlrpc_client_call_asynch_params( - mServerUrl.c_str(), - method_name.c_str(), - callback, - user_data, - param_array.borrowReference()); -} - -inline void XmlRpcClient::event_loop_asynch(unsigned long milliseconds) -{ - xmlrpc_client_event_loop_finish_asynch_timeout(milliseconds); -} - - -//========================================================================= -// XmlRpcClient Methods -//========================================================================= -// These are inline for now, so we don't need to screw with linker issues -// and build a separate client library. - -inline XmlRpcClient::XmlRpcClient (const XmlRpcClient& client) - : mServerUrl(client.mServerUrl) -{ -} - -inline XmlRpcClient& XmlRpcClient::operator= (const XmlRpcClient& client) { - if (this != &client) - mServerUrl = client.mServerUrl; - return *this; -} - -inline void XmlRpcClient::Initialize (string appname, string appversion) { - xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, - appname.c_str(), - appversion.c_str()); -} - -inline void XmlRpcClient::Terminate (void) { - xmlrpc_client_cleanup(); -} - -inline XmlRpcValue XmlRpcClient::call (string method_name, - XmlRpcValue param_array) -{ - XmlRpcEnv env; - xmlrpc_value *result = - xmlrpc_client_call_params(env, - mServerUrl.c_str(), - method_name.c_str(), - param_array.borrowReference()); - env.throwIfFaultOccurred(); - return XmlRpcValue(result, XmlRpcValue::CONSUME_REFERENCE); -} - -//========================================================================= -// XmlRpcGenSrv -//========================================================================= - -class XmlRpcGenSrv { - -private: - - xmlrpc_registry* mRegistry; - - xmlrpc_mem_block* alloc (XmlRpcEnv& env, const string& body) const; - -public: - - XmlRpcGenSrv (int flags); - ~XmlRpcGenSrv (void); - - xmlrpc_registry* getRegistry (void) const; - - XmlRpcGenSrv& addMethod (const string& name, - xmlrpc_method method, - void *data); - XmlRpcGenSrv& addMethod (const string& name, - xmlrpc_method method, - void* data, - const string& signature, - const string& help); - - string handle (const string& body) const; -}; - -inline XmlRpcGenSrv::XmlRpcGenSrv (int flags) { - - XmlRpcEnv env; - - if (flags == flags){}; - - mRegistry = xmlrpc_registry_new (env); - env.throwIfFaultOccurred(); -} - -inline XmlRpcGenSrv::~XmlRpcGenSrv (void) { - - xmlrpc_registry_free (mRegistry); -} - -inline xmlrpc_registry* XmlRpcGenSrv::getRegistry () const { - - return mRegistry; -} - -#undef XMLRPC_NO_ASSIGNMENT - - -// Copyright (C) 2001 by Eric Kidd. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -// SUCH DAMAGE. - - -#endif /* _XMLRPCCPP_H_ */ diff --git a/Utilities/cmxmlrpc/bool.h b/Utilities/cmxmlrpc/bool.h deleted file mode 100644 index 8bf54f34f7..0000000000 --- a/Utilities/cmxmlrpc/bool.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef BOOL_H_INCLUDED -#define BOOL_H_INCLUDED - -#ifndef TRUE -#define TRUE (1) -#endif -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef __cplusplus -#ifndef HAVE_BOOL -#define HAVE_BOOL -typedef int bool; -#endif -#endif - -#endif diff --git a/Utilities/cmxmlrpc/casprintf.c b/Utilities/cmxmlrpc/casprintf.c deleted file mode 100644 index 1fcc7741f0..0000000000 --- a/Utilities/cmxmlrpc/casprintf.c +++ /dev/null @@ -1,35 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include - -#include "xmlrpc_config.h" /* For HAVE_ASPRINTF */ -#include "casprintf.h" - -void GNU_PRINTF_ATTR(2,3) -casprintf(const char ** const retvalP, const char * const fmt, ...) { - - char *retval; - - va_list varargs; /* mysterious structure used by variable arg facility */ - - va_start(varargs, fmt); /* start up the mysterious variable arg facility */ - -#if HAVE_ASPRINTF - vasprintf(&retval, fmt, varargs); -#else - retval = malloc(8192); - vsnprintf(retval, 8192, fmt, varargs); -#endif - *retvalP = retval; -} - - - -void -strfree(const char * const string) { - free((void *)string); -} - - - diff --git a/Utilities/cmxmlrpc/casprintf.h b/Utilities/cmxmlrpc/casprintf.h deleted file mode 100644 index eab336a263..0000000000 --- a/Utilities/cmxmlrpc/casprintf.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CASPRINTF_H_INCLUDED - -/* GNU_PRINTF_ATTR lets the GNU compiler check pm_message() and pm_error() - calls to be sure the arguments match the format string, thus preventing - runtime segmentation faults and incorrect messages. -*/ -#ifdef __GNUC__ -#define GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -#else -#define GNU_PRINTF_ATTR(a,b) -#endif - -void GNU_PRINTF_ATTR(2,3) -casprintf(const char ** const retvalP, const char * const fmt, ...); - -void -strfree(const char * const string); - -#endif diff --git a/Utilities/cmxmlrpc/inline.h b/Utilities/cmxmlrpc/inline.h deleted file mode 100644 index f90032b28a..0000000000 --- a/Utilities/cmxmlrpc/inline.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef XMLRPC_INLINE_H_INCLUDED -#define XMLRPC_INLINE_H_INCLUDED - -/* Xmlrpc-c uses __inline__ to declare functions that should be - compiled as inline code. Some compilers, e.g. GNU, recognize the - __inline__ keyword. -*/ -#ifndef __GNUC__ -#ifndef __inline__ -#ifdef __sgi -#define __inline__ __inline -#else -#define __inline__ -#endif -#endif -#endif - - -#endif diff --git a/Utilities/cmxmlrpc/linklist.h b/Utilities/cmxmlrpc/linklist.h deleted file mode 100644 index b07be84b5e..0000000000 --- a/Utilities/cmxmlrpc/linklist.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef LINKLIST_H_INCLUDED -#define LINKLIST_H_INCLUDED - -#include "inline.h" - -struct list_head { -/*---------------------------------------------------------------------------- - This is a header for an element of a doubly linked list, or an anchor - for such a list. - - itemP == NULL means it's an anchor; otherwise it's a header. - - Initialize a list header with list_init_header(). You don't have to - do anything to terminate a list header. - - Initialize an anchor with list_make_emtpy(). You don't have to do anything - to terminate a list header. ------------------------------------------------------------------------------*/ - struct list_head * nextP; - /* For a header, this is the address of the list header for - the next element in the list. If there is no next element, - it points to the anchor. If the header is not in a list at - all, it is NULL. - - For an anchor, it is the address of the list header of the - first element. If the list is empty, it points to the - anchor itself. - */ - struct list_head * prevP; - /* For a header, this is the address of the list header for - the previous element in the list. If there is no previous element, - it points to the anchor. If the header is not in a list at - all, it is NULL. - - For an anchor, it is the address of the list header of the - last element. If the list is empty, it points to the - anchor itself. - */ - void * itemP; - /* For a header, this is the address of the list element to which it - belongs. For an anchor, this is NULL. - */ -}; - -static __inline__ void -list_init_header(struct list_head * const headerP, - void * const itemP) { - - headerP->prevP = NULL; - headerP->nextP = NULL; - headerP->itemP = itemP; -} - - - -static __inline__ int -list_is_linked(struct list_head * headerP) { - return headerP->prevP != NULL; -} - - - -static __inline__ int -list_is_empty(struct list_head * const anchorP) { - return anchorP->nextP == anchorP; -} - - - -static __inline__ unsigned int -list_count(struct list_head * const anchorP) { - unsigned int count; - - struct list_head * p; - - for (p = anchorP->nextP, count = 0; - p != anchorP; - p = p->nextP, ++count); - - return count; -} - - - -static __inline__ void -list_make_empty(struct list_head * const anchorP) { - anchorP->prevP = anchorP; - anchorP->nextP = anchorP; - anchorP->itemP = NULL; -} - -static __inline__ void -list_insert_after(struct list_head * const beforeHeaderP, - struct list_head * const newHeaderP) { - newHeaderP->prevP = beforeHeaderP; - newHeaderP->nextP = beforeHeaderP->nextP; - - beforeHeaderP->nextP = newHeaderP; - newHeaderP->nextP->prevP = newHeaderP; -} - - - -static __inline__ void -list_add_tail(struct list_head * const anchorP, - struct list_head * const headerP) { - list_insert_after(anchorP->prevP, headerP); -} - - - -static __inline__ void -list_add_head(struct list_head * const anchorP, - struct list_head * const headerP) { - list_insert_after(anchorP, headerP); -} - - - -static __inline__ void -list_remove(struct list_head * const headerP) { - headerP->prevP->nextP = headerP->nextP; - headerP->nextP->prevP = headerP->prevP; - headerP->prevP = NULL; - headerP->nextP = NULL; -} - - - -static __inline__ struct list_head * -list_remove_head(struct list_head * const anchorP) { - struct list_head * retval; - - if (list_is_empty(anchorP)) - retval = NULL; - else { - retval = anchorP->nextP; - list_remove(retval); - } - return retval; -} - - - -static __inline__ struct list_head * -list_remove_tail(struct list_head * const anchorP) { - struct list_head * retval; - - if (list_is_empty(anchorP)) - retval = NULL; - else { - retval = anchorP->prevP; - list_remove(retval); - } - return retval; -} - - - -static __inline__ void * -list_foreach(struct list_head * const anchorP, - void * functionP(struct list_head * const, void * const), - void * const context) { - - struct list_head * p; - struct list_head * nextP; - void * result; - - for (p = anchorP->nextP, nextP = p->nextP, result=NULL; - p != anchorP && result == NULL; - p = nextP, nextP = p->nextP) - result = (*functionP)(p, context); - - return result; -} - - - -static __inline__ void -list_append(struct list_head * const newAnchorP, - struct list_head * const baseAnchorP) { - - if (!list_is_empty(newAnchorP)) { - baseAnchorP->prevP->nextP = newAnchorP->nextP; - newAnchorP->nextP->prevP = baseAnchorP->prevP; - newAnchorP->prevP->nextP = baseAnchorP; - baseAnchorP->prevP = newAnchorP->prevP; - } -} - -#endif - - diff --git a/Utilities/cmxmlrpc/mallocvar.h b/Utilities/cmxmlrpc/mallocvar.h deleted file mode 100644 index f2022e95f4..0000000000 --- a/Utilities/cmxmlrpc/mallocvar.h +++ /dev/null @@ -1,80 +0,0 @@ -/* These are some dynamic memory allocation facilities. They are essentially - an extension to C, as they do allocations with a cognizance of C - variables. You can use them to make C read more like a high level - language. -*/ - -#ifndef MALLOCVAR_INCLUDED -#define MALLOCVAR_INCLUDED - -#include -#include - -static __inline__ void -mallocProduct(void ** const resultP, - unsigned int const factor1, - unsigned int const factor2) { -/*---------------------------------------------------------------------------- - malloc a space whose size in bytes is the product of 'factor1' and - 'factor2'. But if that size cannot be represented as an unsigned int, - return NULL without allocating anything. Also return NULL if the malloc - fails. - - Note that malloc() actually takes a size_t size argument, so the - proper test would be whether the size can be represented by size_t, - not unsigned int. But there is no reliable indication available to - us, like UINT_MAX, of what the limitations of size_t are. We - assume size_t is at least as expressive as unsigned int and that - nobody really needs to allocate more than 4GB of memory. ------------------------------------------------------------------------------*/ - if (UINT_MAX / factor2 < factor1) - *resultP = NULL; \ - else - *resultP = malloc(factor1 * factor2); -} - - - -static __inline__ void -reallocProduct(void ** const blockP, - unsigned int const factor1, - unsigned int const factor2) { - - if (UINT_MAX / factor2 < factor1) - *blockP = NULL; \ - else - *blockP = realloc(*blockP, factor1 * factor2); -} - - - -#define MALLOCARRAY(arrayName, nElements) \ - mallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0])) - -#define REALLOCARRAY(arrayName, nElements) \ - reallocProduct((void **)&arrayName, nElements, sizeof(arrayName[0])) - - -#define MALLOCARRAY_NOFAIL(arrayName, nElements) \ -do { \ - MALLOCARRAY(arrayName, nElements); \ - if ((arrayName) == NULL) \ - abort(); \ -} while(0) - -#define REALLOCARRAY_NOFAIL(arrayName, nElements) \ -do { \ - REALLOCARRAY(arrayName, nElements); \ - if ((arrayName) == NULL) \ - abort(); \ -} while(0) - - -#define MALLOCVAR(varName) \ - varName = malloc(sizeof(*varName)) - -#define MALLOCVAR_NOFAIL(varName) \ - do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0) - -#endif - diff --git a/Utilities/cmxmlrpc/synch_client.c b/Utilities/cmxmlrpc/synch_client.c deleted file mode 100644 index 7c814858fa..0000000000 --- a/Utilities/cmxmlrpc/synch_client.c +++ /dev/null @@ -1,68 +0,0 @@ -/* A simple synchronous XML-RPC client written in C. */ - -#include -#include - -#include -#include - -#define NAME "XML-RPC C Test Client" -#define VERSION "0.1" - -static void die_if_fault_occurred (xmlrpc_env *env) -{ - if (env->fault_occurred) { - fprintf(stderr, "XML-RPC Fault: %s (%d)\n", - env->fault_string, env->fault_code); - exit(1); - } -} - - - -int -main(int const argc, - const char ** const argv ATTR_UNUSED) { - - xmlrpc_env env; - char *state_name; - int cc; - - if (argc-1 > 0) { - fprintf(stderr, "No arguments"); - exit(0); - } - - /* Start up our XML-RPC client library. */ - xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION); - - /* Initialize our error-handling environment. */ - xmlrpc_env_init(&env); - - /* Call the famous server at UserLand. */ - for ( cc = 30; cc < 35; cc ++ ) - { - xmlrpc_value *result; - result = xmlrpc_client_call(&env, "http://betty.userland.com/RPC2", - "examples.getStateName", - "(i)", (xmlrpc_int32) cc); - die_if_fault_occurred(&env); - - /* Get our state name and print it out. */ - xmlrpc_parse_value(&env, result, "s", &state_name); - die_if_fault_occurred(&env); - printf("%d: %s\n", cc, state_name); - - /* Dispose of our result value. */ - xmlrpc_DECREF(result); - - } - - /* Clean up our error-handling environment. */ - xmlrpc_env_clean(&env); - - /* Shutdown our XML-RPC client library. */ - xmlrpc_client_cleanup(); - - return 0; -} diff --git a/Utilities/cmxmlrpc/transport_config.h b/Utilities/cmxmlrpc/transport_config.h deleted file mode 100644 index 790070392e..0000000000 --- a/Utilities/cmxmlrpc/transport_config.h +++ /dev/null @@ -1,5 +0,0 @@ -/* This file was generated by a make rule */ -#define MUST_BUILD_WININET_CLIENT 0 -#define MUST_BUILD_CURL_CLIENT 1 -#define MUST_BUILD_LIBWWW_CLIENT 0 -static const char * const XMLRPC_DEFAULT_TRANSPORT = "libcurl"; diff --git a/Utilities/cmxmlrpc/win32_pthreads.c b/Utilities/cmxmlrpc/win32_pthreads.c deleted file mode 100644 index 8f736ca583..0000000000 --- a/Utilities/cmxmlrpc/win32_pthreads.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#ifdef _WIN32 - -#define HAVE_PTHREADS 1 -#include "xmlrpc_pthreads.h" - -#include - -#undef PACKAGE -#undef VERSION - -#include "xmlrpc.h" - -int pthread_create(pthread_t *new_thread_ID, - const pthread_attr_t * attr, - pthread_func start_func, void *arg) -{ - HANDLE hThread; - unsigned dwThreadID; - - XMLRPC_ASSERT (attr == NULL); /* unimplemented. */ - XMLRPC_ASSERT_PTR_OK(new_thread_ID); - XMLRPC_ASSERT_PTR_OK(start_func); - XMLRPC_ASSERT_PTR_OK(arg); - - hThread = (HANDLE) _beginthreadex (NULL, 0, - start_func, (LPVOID)arg, CREATE_SUSPENDED, &dwThreadID); - - SetThreadPriority (hThread, THREAD_PRIORITY_NORMAL); - ResumeThread (hThread); - - *new_thread_ID = hThread; - - return hThread ? 0 : -1; -} - -/* Just kill it. */ -int pthread_cancel(pthread_t target_thread) -{ - CloseHandle (target_thread); - return 0; -} - -/* Waits for the thread to exit before continuing. */ -int pthread_join(pthread_t target_thread, void **status) -{ - DWORD dwResult = WaitForSingleObject(target_thread, INFINITE); - (*status) = (void *)dwResult; - return 0; -} - -/* Stubbed. Do nothing. */ -int pthread_detach(pthread_t target_thread) -{ - return 0; -} - -int pthread_mutex_init(pthread_mutex_t *mp, - const pthread_mutexattr_t * attr) -{ - InitializeCriticalSection(mp); - return 0; -} - -int pthread_mutex_lock(pthread_mutex_t *mp) -{ - EnterCriticalSection(mp); - return 0; -} - -int pthread_mutex_unlock(pthread_mutex_t *mp) -{ - LeaveCriticalSection(mp); - return 0; -} - -int pthread_mutex_destroy(pthread_mutex_t *mp) -{ - DeleteCriticalSection(mp); - return 0; -} - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc.h b/Utilities/cmxmlrpc/xmlrpc.h deleted file mode 100644 index 30b83842ac..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc.h +++ /dev/null @@ -1,784 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#ifndef _XMLRPC_H_ -#define _XMLRPC_H_ 1 - -#include -#include -#include - -#ifdef HAVE_UNICODE_WCHAR -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/*========================================================================= -** Typedefs -**========================================================================= -** We define names for these types, because they may change from platform -** to platform. -*/ - -typedef signed int xmlrpc_int; - /* An integer of the type defined by XML-RPC ; i.e. 32 bit */ -typedef signed int xmlrpc_int32; - /* An integer of the type defined by XML-RPC ; i.e. 32 bit */ -typedef int xmlrpc_bool; - /* A boolean (of the type defined by XML-RPC , but there's - really only one kind) - */ -typedef double xmlrpc_double; - /* A double precision floating point number as defined by - XML-RPC . But the C "double" type is universally the same, - so it's probably clearer just to use that. This typedef is here - for mathematical completeness. - */ - -#define XMLRPC_INT32_MAX (2147483647) -#define XMLRPC_INT32_MIN (-XMLRPC_INT32_MAX - 1) - - - -/*========================================================================= -** C struct size computations -**=======================================================================*/ - -/* Use XMLRPC_STRUCT_MEMBER_SIZE() to determine how big a structure is - up to and including a specified member. E.g. if you have - struct mystruct {int red; int green; int blue};, then - XMLRPC_STRUCT_MEMBER_SIZE(mystruct, green) is (8). -*/ - -#define _XMLRPC_STRUCT_MEMBER_OFFSET(TYPE, MBRNAME) \ - ((unsigned int)(char*)&((TYPE *)0)->MBRNAME) -#define _XMLRPC_STRUCT_MEMBER_SIZE(TYPE, MBRNAME) \ - sizeof(((TYPE *)0)->MBRNAME) -#define XMLRPC_STRUCTSIZE(TYPE, MBRNAME) \ - (_XMLRPC_STRUCT_MEMBER_OFFSET(TYPE, MBRNAME) + \ - _XMLRPC_STRUCT_MEMBER_SIZE(TYPE, MBRNAME)) - -/*========================================================================= -** Assertions and Debugging -**========================================================================= -** We use xmlrpc_assert for internal sanity checks. For example: -** -** xmlrpc_assert(ptr != NULL); -** -** Assertions are only evaluated when debugging code is turned on. (To -** turn debugging off, define NDEBUG.) Some rules for using assertions: -** -** 1) Assertions should never have side effects. -** 2) Assertions should never be used for run-time error checking. -** Instead, they should be used to check for "can't happen" errors. -*/ - -#ifndef NDEBUG - -#define XMLRPC_ASSERT(cond) \ - do \ - if (!(cond)) \ - xmlrpc_assertion_failed(__FILE__, __LINE__); \ - while (0) - -#else -#define XMLRPC_ASSERT(cond) (0) -#endif - -extern void xmlrpc_assertion_failed (char* file, int line); - -/* Validate a pointer. */ -#define XMLRPC_ASSERT_PTR_OK(ptr) \ - XMLRPC_ASSERT((ptr) != NULL) - -/* We only call this if something truly drastic happens. */ -#define XMLRPC_FATAL_ERROR(msg) xmlrpc_fatal_error(__FILE__, __LINE__, (msg)) - -extern void xmlrpc_fatal_error (char* file, int line, char* msg); - - -/*========================================================================= -** Strings -**=======================================================================*/ - -/* Traditional C strings are char *, because they come from a time before - there was 'const'. Now, const char * makes a lot more sense. Also, - in modern times, we tend to dynamically allocate memory for strings. - We need this free function accordingly. Ordinary free() doesn't check - the type, and can generate a warning due to the 'const'. -*/ -void -xmlrpc_strfree(const char * const string); - - - -/*========================================================================= -** xmlrpc_env -**========================================================================= -** XML-RPC represents runtime errors as elements. These contain -** and elements. -** -** Since we need as much thread-safety as possible, we borrow an idea from -** CORBA--we store exception information in an "environment" object. -** You'll pass this to many different functions, and it will get filled -** out appropriately. -** -** For example: -** -** xmlrpc_env env; -** -** xmlrpc_env_init(&env); -** -** xmlrpc_do_something(&env); -** if (env.fault_occurred) -** report_error_appropriately(); -** -** xmlrpc_env_clean(&env); -*/ - -#define XMLRPC_INTERNAL_ERROR (-500) -#define XMLRPC_TYPE_ERROR (-501) -#define XMLRPC_INDEX_ERROR (-502) -#define XMLRPC_PARSE_ERROR (-503) -#define XMLRPC_NETWORK_ERROR (-504) -#define XMLRPC_TIMEOUT_ERROR (-505) -#define XMLRPC_NO_SUCH_METHOD_ERROR (-506) -#define XMLRPC_REQUEST_REFUSED_ERROR (-507) -#define XMLRPC_INTROSPECTION_DISABLED_ERROR (-508) -#define XMLRPC_LIMIT_EXCEEDED_ERROR (-509) -#define XMLRPC_INVALID_UTF8_ERROR (-510) - -typedef struct _xmlrpc_env { - int fault_occurred; - xmlrpc_int32 fault_code; - char* fault_string; -} xmlrpc_env; - -/* Initialize and destroy the contents of the provided xmlrpc_env object. -** These functions will never fail. */ -void xmlrpc_env_init (xmlrpc_env* env); -void xmlrpc_env_clean (xmlrpc_env* env); - -/* Fill out an xmlrpc_fault with the specified values, and set the -** fault_occurred flag. This function will make a private copy of 'string', -** so you retain responsibility for your copy. */ -void -xmlrpc_env_set_fault(xmlrpc_env * const env, - int const faultCode, - const char * const faultDescription); - -/* The same as the above, but using a printf-style format string. */ -void -xmlrpc_env_set_fault_formatted (xmlrpc_env * const envP, - int const code, - const char * const format, - ...); - -/* A simple debugging assertion. */ -#define XMLRPC_ASSERT_ENV_OK(env) \ - XMLRPC_ASSERT((env) != NULL && !(env)->fault_occurred) - -/* This version must *not* interpret 'str' as a format string, to avoid -** several evil attacks. */ -#define XMLRPC_FAIL(env,code,str) \ - do { xmlrpc_env_set_fault((env),(code),(str)); if(*(str)) goto cleanup; } while (0) - -#define XMLRPC_FAIL1(env,code,str,arg1) \ - do { \ - xmlrpc_env_set_fault_formatted((env),(code),(str),(arg1)); \ - if(*(str)) goto cleanup; \ - } while (0) - -#define XMLRPC_FAIL2(env,code,str,arg1,arg2) \ - do { \ - xmlrpc_env_set_fault_formatted((env),(code),(str),(arg1),(arg2)); \ - if(*(str)) goto cleanup; \ - } while (0) - -#define XMLRPC_FAIL3(env,code,str,arg1,arg2,arg3) \ - do { \ - xmlrpc_env_set_fault_formatted((env),(code), \ - (str),(arg1),(arg2),(arg3)); \ - if(*(str)) goto cleanup; \ - } while (0) - -#define XMLRPC_FAIL_IF_NULL(ptr,env,code,str) \ - do { \ - if ((ptr) == NULL) \ - XMLRPC_FAIL((env),(code),(str)); \ - } while (0) - -#define XMLRPC_FAIL_IF_FAULT(env) \ - do { if ((env)->fault_occurred) goto cleanup; } while (0) - - -/*========================================================================= -** Resource Limits -**========================================================================= -** To discourage denial-of-service attacks, we provide several adjustable -** resource limits. These functions are *not* re-entrant. -*/ - -/* Limit IDs. There will be more of these as time goes on. */ -#define XMLRPC_NESTING_LIMIT_ID (0) -#define XMLRPC_XML_SIZE_LIMIT_ID (1) -#define XMLRPC_LAST_LIMIT_ID (XMLRPC_XML_SIZE_LIMIT_ID) - -/* By default, deserialized data may be no more than 64 levels deep. */ -#define XMLRPC_NESTING_LIMIT_DEFAULT (64) - -/* By default, XML data from the network may be no larger than 512K. -** Some client and server modules may fail to enforce this properly. */ -#define XMLRPC_XML_SIZE_LIMIT_DEFAULT (512*1024) - -/* Set a specific limit to the specified value. */ -extern void xmlrpc_limit_set (int limit_id, size_t value); - -/* Get the value of a specified limit. */ -extern size_t xmlrpc_limit_get (int limit_id); - - -/*========================================================================= -** xmlrpc_mem_block -**========================================================================= -** A resizable chunk of memory. This is mostly used internally, but it is -** also used by the public API in a few places. -** The struct fields are private! -*/ - -typedef struct _xmlrpc_mem_block { - size_t _size; - size_t _allocated; - void* _block; -} xmlrpc_mem_block; - -/* Allocate a new xmlrpc_mem_block. */ -xmlrpc_mem_block* xmlrpc_mem_block_new (xmlrpc_env* const env, size_t const size); - -/* Destroy an existing xmlrpc_mem_block, and everything it contains. */ -void xmlrpc_mem_block_free (xmlrpc_mem_block* block); - -/* Initialize the contents of the provided xmlrpc_mem_block. */ -void xmlrpc_mem_block_init - (xmlrpc_env* env, xmlrpc_mem_block* block, size_t size); - -/* Deallocate the contents of the provided xmlrpc_mem_block, but not the -** block itself. */ -void xmlrpc_mem_block_clean (xmlrpc_mem_block* block); - -/* Get the size and contents of the xmlrpc_mem_block. */ -size_t -xmlrpc_mem_block_size(const xmlrpc_mem_block * const block); - -void * -xmlrpc_mem_block_contents(const xmlrpc_mem_block * const block); - -/* Resize an xmlrpc_mem_block, preserving as much of the contents as -** possible. */ -void xmlrpc_mem_block_resize - (xmlrpc_env* const env, xmlrpc_mem_block* const block, size_t const size); - -/* Append data to an existing xmlrpc_mem_block. */ -void xmlrpc_mem_block_append - (xmlrpc_env* const env, xmlrpc_mem_block* const block, void *const data, size_t const len); - -#define XMLRPC_MEMBLOCK_NEW(type,env,size) \ - xmlrpc_mem_block_new((env), sizeof(type) * (size)) -#define XMLRPC_MEMBLOCK_FREE(type,block) \ - xmlrpc_mem_block_free(block) -#define XMLRPC_MEMBLOCK_INIT(type,env,block,size) \ - xmlrpc_mem_block_init((env), (block), sizeof(type) * (size)) -#define XMLRPC_MEMBLOCK_CLEAN(type,block) \ - xmlrpc_mem_block_clean(block) -#define XMLRPC_MEMBLOCK_SIZE(type,block) \ - (xmlrpc_mem_block_size(block) / sizeof(type)) -#define XMLRPC_MEMBLOCK_CONTENTS(type,block) \ - ((type*) xmlrpc_mem_block_contents(block)) -#define XMLRPC_MEMBLOCK_RESIZE(type,env,block,size) \ - xmlrpc_mem_block_resize(env, block, sizeof(type) * (size)) -#define XMLRPC_MEMBLOCK_APPEND(type,env,block,data,size) \ - xmlrpc_mem_block_append(env, block, data, sizeof(type) * (size)) - -/* Here are some backward compatibility definitions. These longer names - used to be the only ones and typed memory blocks were considered - special. -*/ -#define XMLRPC_TYPED_MEM_BLOCK_NEW(type,env,size) \ - XMLRPC_MEMBLOCK_NEW(type,env,size) -#define XMLRPC_TYPED_MEM_BLOCK_FREE(type,block) \ - XMLRPC_MEMBLOCK_FREE(type,block) -#define XMLRPC_TYPED_MEM_BLOCK_INIT(type,env,block,size) \ - XMLRPC_MEMBLOCK_INIT(type,env,block,size) -#define XMLRPC_TYPED_MEM_BLOCK_CLEAN(type,block) \ - XMLRPC_MEMBLOCK_CLEAN(type,block) -#define XMLRPC_TYPED_MEM_BLOCK_SIZE(type,block) \ - XMLRPC_MEMBLOCK_SIZE(type,block) -#define XMLRPC_TYPED_MEM_BLOCK_CONTENTS(type,block) \ - XMLRPC_MEMBLOCK_CONTENTS(type,block) -#define XMLRPC_TYPED_MEM_BLOCK_RESIZE(type,env,block,size) \ - XMLRPC_MEMBLOCK_RESIZE(type,env,block,size) -#define XMLRPC_TYPED_MEM_BLOCK_APPEND(type,env,block,data,size) \ - XMLRPC_MEMBLOCK_APPEND(type,env,block,data,size) - - - -/*========================================================================= -** xmlrpc_value -**========================================================================= -** An XML-RPC value (of any type). -*/ - -typedef enum { - XMLRPC_TYPE_INT = 0, - XMLRPC_TYPE_BOOL = 1, - XMLRPC_TYPE_DOUBLE = 2, - XMLRPC_TYPE_DATETIME = 3, - XMLRPC_TYPE_STRING = 4, - XMLRPC_TYPE_BASE64 = 5, - XMLRPC_TYPE_ARRAY = 6, - XMLRPC_TYPE_STRUCT = 7, - XMLRPC_TYPE_C_PTR = 8, - XMLRPC_TYPE_DEAD = 0xDEAD -} xmlrpc_type; - -/* These are *always* allocated on the heap. No exceptions. */ -typedef struct _xmlrpc_value xmlrpc_value; - -#define XMLRPC_ASSERT_VALUE_OK(val) \ - XMLRPC_ASSERT((val) != NULL && (val)->_type != XMLRPC_TYPE_DEAD) - -/* A handy type-checking routine. */ -#define XMLRPC_TYPE_CHECK(env,v,t) \ - do \ - if ((v)->_type != (t)) \ - XMLRPC_FAIL(env, XMLRPC_TYPE_ERROR, "Expected " #t); \ - while (0) - -void -xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP); - -#define XMLRPC_ASSERT_ARRAY_OK(val) \ - xmlrpc_abort_if_array_bad(val) - -/* Increment the reference count of an xmlrpc_value. */ -extern void xmlrpc_INCREF (xmlrpc_value* const value); - -/* Decrement the reference count of an xmlrpc_value. If there -** are no more references, free it. */ -extern void xmlrpc_DECREF (xmlrpc_value* const value); - -/* Get the type of an XML-RPC value. */ -extern xmlrpc_type xmlrpc_value_type (xmlrpc_value* value); - -/* Build an xmlrpc_value from a format string. -** Increments the reference counts of input arguments if necessary. -** See the xmlrpc-c documentation for more information. */ -xmlrpc_value * -xmlrpc_build_value(xmlrpc_env * const env, - const char * const format, - ...); - -/* The same as the above, but using a va_list and more general */ -void -xmlrpc_build_value_va(xmlrpc_env * const env, - const char * const format, - va_list args, - xmlrpc_value ** const valPP, - const char ** const tailP); - -/* Extract values from an xmlrpc_value and store them into C variables. -** Does not increment the reference counts of output values. -** See the xmlrpc-c documentation for more information. */ -void -xmlrpc_parse_value(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - ...); - -/* The same as the above, but using a va_list. */ -void -xmlrpc_parse_value_va(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - va_list args); - -void -xmlrpc_read_int(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - int * const intValueP); - -void -xmlrpc_read_double(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_double * const doubleValueP); - -void -xmlrpc_read_bool(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_bool * const boolValueP); - -void -xmlrpc_read_string(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP); - - -void -xmlrpc_read_string_lp(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - unsigned int * const lengthP, - const char ** const stringValueP); - -/* Return the number of elements in an XML-RPC array. -** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */ -int -xmlrpc_array_size(xmlrpc_env * const env, - const xmlrpc_value * const array); - -/* Append an item to an XML-RPC array. -** Increments the reference count of 'value' if no fault occurs. -** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */ -extern void -xmlrpc_array_append_item (xmlrpc_env* const env, - xmlrpc_value* const array, - xmlrpc_value* const value); - -void -xmlrpc_array_read_item(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - unsigned int const xmIndex, - xmlrpc_value ** const valuePP); - -/* Get an item from an XML-RPC array. -** Does not increment the reference count of the returned value. -** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. -** Sets XMLRPC_INDEX_ERROR if 'index' is out of bounds. */ -xmlrpc_value * -xmlrpc_array_get_item(xmlrpc_env * const env, - const xmlrpc_value * const array, - int const xmIndex); - -/* Not implemented--we don't need it yet. -extern -int xmlrpc_array_set_item (xmlrpc_env* env, -xmlrpc_value* array, -int index, - xmlrpc_value* value); -*/ - -/* Create a new struct. Deprecated. xmlrpc_build_value() is the - general way to create an xmlrpc_value, including an empty struct. -*/ -xmlrpc_value * -xmlrpc_struct_new(xmlrpc_env * env); - -/* Return the number of key/value pairs in a struct. -** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */ -int -xmlrpc_struct_size (xmlrpc_env * env, - xmlrpc_value * strct); - -/* Returns true iff 'strct' contains 'key'. -** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */ -int -xmlrpc_struct_has_key(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key); - -/* The same as the above, but the key may contain zero bytes. - Deprecated. xmlrpc_struct_get_value_v() is more general, and this - case is not common enough to warrant a shortcut. -*/ -int -xmlrpc_struct_has_key_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len); - -#if 0 -/* Not implemented yet, but needed for completeness. */ -int -xmlrpc_struct_has_key_v(xmlrpc_env * env, - xmlrpc_value * strct, - xmlrpc_value * const keyval); -#endif - - -void -xmlrpc_struct_find_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP); - - -void -xmlrpc_struct_find_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP); - -void -xmlrpc_struct_read_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP); - -void -xmlrpc_struct_read_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - xmlrpc_value ** const valuePP); - -/* The "get_value" functions are deprecated. Use the "find_value" - and "read_value" functions instead. -*/ -xmlrpc_value * -xmlrpc_struct_get_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key); - -/* The same as above, but the key may contain zero bytes. - Deprecated. xmlrpc_struct_get_value_v() is more general, and this - case is not common enough to warrant a shortcut. -*/ -xmlrpc_value * -xmlrpc_struct_get_value_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len); - -/* Set the value associated with 'key' in 'strct' to 'value'. -** Increments the reference count of value. -** Sets XMLRPC_TYPE_ERROR if 'strct' is not a struct. */ -void -xmlrpc_struct_set_value(xmlrpc_env * const env, - xmlrpc_value * const strct, - const char * const key, - xmlrpc_value * const value); - -/* The same as above, but the key may contain zero bytes. Deprecated. - The general way to set a structure value is xmlrpc_struct_set_value_v(), - and this case is not common enough to deserve a shortcut. -*/ -void -xmlrpc_struct_set_value_n(xmlrpc_env * const env, - xmlrpc_value * const strct, - const char * const key, - size_t const key_len, - xmlrpc_value * const value); - -/* The same as above, but the key must be an XML-RPC string. -** Fails with XMLRPC_TYPE_ERROR if 'keyval' is not a string. */ -void -xmlrpc_struct_set_value_v(xmlrpc_env * const env, - xmlrpc_value * const strct, - xmlrpc_value * const keyval, - xmlrpc_value * const value); - -/* Given a zero-based index, return the matching key and value. This -** is normally used in conjunction with xmlrpc_struct_size. -** Fails with XMLRPC_TYPE_ERROR if 'struct' is not a struct. -** Fails with XMLRPC_INDEX_ERROR if 'index' is out of bounds. */ - -void -xmlrpc_struct_read_member(xmlrpc_env * const envP, - xmlrpc_value * const structP, - unsigned int const xmIndex, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP); - -/* The same as above, but does not increment the reference count of the - two values it returns, and return NULL for both if it fails, and - takes a signed integer for the index (but fails if it is negative). - - Deprecated. -*/ -void -xmlrpc_struct_get_key_and_value(xmlrpc_env * const env, - xmlrpc_value * const strct, - int const xmIndex, - xmlrpc_value ** const out_keyval, - xmlrpc_value ** const out_value); - - -/*========================================================================= -** Encoding XML -**=======================================================================*/ - -/* Serialize an XML value without any XML header. This is primarily used -** for testing purposes. */ -void -xmlrpc_serialize_value(xmlrpc_env * env, - xmlrpc_mem_block * output, - xmlrpc_value * value); - -/* Serialize a list of parameters without any XML header. This is -** primarily used for testing purposes. */ -void -xmlrpc_serialize_params(xmlrpc_env * env, - xmlrpc_mem_block * output, - xmlrpc_value * param_array); - -/* Serialize an XML-RPC call. */ -void -xmlrpc_serialize_call (xmlrpc_env * const env, - xmlrpc_mem_block * const output, - const char * const method_name, - xmlrpc_value * const param_array); - -/* Serialize an XML-RPC return value. */ -extern void -xmlrpc_serialize_response(xmlrpc_env * env, - xmlrpc_mem_block * output, - xmlrpc_value * value); - -/* Serialize an XML-RPC fault (as specified by 'fault'). */ -extern void -xmlrpc_serialize_fault(xmlrpc_env * env, - xmlrpc_mem_block * output, - xmlrpc_env * fault); - - -/*========================================================================= -** Decoding XML -**=======================================================================*/ - -/* Parse an XML-RPC call. If an error occurs, set a fault and set -** the output variables to NULL. -** The caller is responsible for calling free(*out_method_name) and -** xmlrpc_DECREF(*out_param_array). */ -void -xmlrpc_parse_call(xmlrpc_env * const envP, - const char * const xml_data, - size_t const xml_len, - const char ** const out_method_name, - xmlrpc_value ** const out_param_array); - -/* Parse an XML-RPC response. If a fault occurs (or was received over the -** wire), return NULL and set up 'env'. The calling is responsible for -** calling xmlrpc_DECREF on the return value (if it isn't NULL). */ -xmlrpc_value * -xmlrpc_parse_response(xmlrpc_env * env, - const char * xml_data, - size_t xml_len); - - -/*========================================================================= -** XML-RPC Base64 Utilities -**========================================================================= -** Here are some lightweight utilities which can be used to encode and -** decode Base64 data. These are exported mainly for testing purposes. -*/ - -/* This routine inserts newlines every 76 characters, as required by the -** Base64 specification. */ -xmlrpc_mem_block * -xmlrpc_base64_encode(xmlrpc_env * env, - unsigned char * bin_data, - size_t bin_len); - -/* This routine encodes everything in one line. This is needed for HTTP -** authentication and similar tasks. */ -xmlrpc_mem_block * -xmlrpc_base64_encode_without_newlines(xmlrpc_env * env, - unsigned char * bin_data, - size_t bin_len); - -/* This decodes Base64 data with or without newlines. */ -extern xmlrpc_mem_block * -xmlrpc_base64_decode(xmlrpc_env * env, - char * ascii_data, - size_t ascii_len); - - -/*========================================================================= -** UTF-8 Encoding and Decoding -**========================================================================= -** We need a correct, reliable and secure UTF-8 decoder. This decoder -** raises a fault if it encounters invalid UTF-8. -** -** Note that ANSI C does not precisely define the representation used -** by wchar_t--it may be UCS-2, UTF-16, UCS-4, or something from outer -** space. If your platform does something especially bizarre, you may -** need to reimplement these routines. -*/ - -#ifdef HAVE_UNICODE_WCHAR - -/* Ensure that a string contains valid, legally-encoded UTF-8 data. -** (Incorrectly-encoded UTF-8 strings are often used to bypass security -** checks.) */ -void -xmlrpc_validate_utf8 (xmlrpc_env * const env, - const char * const utf8_data, - size_t const utf8_len); - -/* Decode a UTF-8 string. */ -xmlrpc_mem_block * -xmlrpc_utf8_to_wcs(xmlrpc_env * env, - char * utf8_data, - size_t utf8_len); - -/* Encode a UTF-8 string. */ -xmlrpc_mem_block * -xmlrpc_wcs_to_utf8(xmlrpc_env * env, - wchar_t * wcs_data, - size_t wcs_len); - -#endif /* HAVE_UNICODE_WCHAR */ - -/*========================================================================= -** Authorization Cookie Handling -**========================================================================= -** Routines to get and set values for authorizing via authorization -** cookies. Both the client and server use HTTP_COOKIE_AUTH to store -** the representation of the authorization value, which is actually -** just a base64 hash of username:password. (This entire method is -** a cookie replacement of basic authentication.) -**/ - -extern void xmlrpc_authcookie_set(xmlrpc_env * env, - const char * username, - const char * password); - -char *xmlrpc_authcookie(void); - -#ifdef __cplusplus -} -#endif - -/* In the days before xmlrpc_server.h existed, some of what's in it was - in here. For backward compatibility, we need to include it here, even - though it really isn't logical to do so. -*/ -#include - -#endif - diff --git a/Utilities/cmxmlrpc/xmlrpc_amconfig.h.in b/Utilities/cmxmlrpc/xmlrpc_amconfig.h.in deleted file mode 100644 index 0b3552a235..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_amconfig.h.in +++ /dev/null @@ -1,37 +0,0 @@ -/* xmlrpc_amconfig.h is generated by 'configure' from the template - xmlrpc_amconfig.h.in, by virtue of the AM_CONFIG_HEADER() macro in - configure.in. - - We'd like to replace it some day with something that doesn't use - such a special tool, to make the build understandable by dumber - developers. -*/ - -/* Define to `unsigned' if doesn't define. */ -#cmakedefine size_t @size_t@ - -/* Define if you have the setgroups function. */ -#cmakedefine HAVE_SETGROUPS @HAVE_SETGROUPS@ - -#cmakedefine HAVE_ASPRINTF @HAVE_ASPRINTF@ - -/* Define if you have the wcsncmp function. */ -#cmakedefine HAVE_WCSNCMP @HAVE_WCSNCMP@ - -/* Define if you have the header file. */ -#cmakedefine HAVE_STDARG_H @HAVE_STDARG_H@ - -/* Define if you have the header file. */ -#cmakedefine HAVE_SYS_FILIO_H @HAVE_SYS_FILIO_H@ - -/* Define if you have the header file. */ -#cmakedefine HAVE_SYS_IOCTL_H @HAVE_SYS_IOCTL_H@ - -/* Define if you have the header file. */ -#cmakedefine HAVE_WCHAR_H @HAVE_WCHAR_H@ - -/* Define if you have the socket library (-lsocket). */ -#cmakedefine HAVE_LIBSOCKET @HAVE_LIBSOCKET@ - -/* Name of package */ -#cmakedefine PACKAGE @PACKAGE@ diff --git a/Utilities/cmxmlrpc/xmlrpc_array.c b/Utilities/cmxmlrpc/xmlrpc_array.c deleted file mode 100644 index 36010c67c8..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_array.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright information is at the end of the file */ - -/*========================================================================= -** XML-RPC Array Functions -**========================================================================= -*/ - -#include "xmlrpc_config.h" - -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" - - -void -xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) { - - if (arrayP == NULL) - abort(); - else if (arrayP->_type != XMLRPC_TYPE_ARRAY) - abort(); - else { - size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); - - if (contents == NULL) - abort(); - else { - unsigned int xmIndex; - - for (xmIndex = 0; xmIndex < arraySize; ++xmIndex) { - xmlrpc_value * const itemP = contents[xmIndex]; - if (itemP == NULL) - abort(); - else if (itemP->_refcount < 1) - abort(); - } - } - } -} - - - -void -xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { -/*---------------------------------------------------------------------------- - Dispose of the contents of an array (but not the array value itself). - The value is not valid after this. ------------------------------------------------------------------------------*/ - size_t const arraySize = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); - - unsigned int xmIndex; - - XMLRPC_ASSERT_ARRAY_OK(arrayP); - - /* Release our reference to each item in the array */ - for (xmIndex = 0; xmIndex < arraySize; ++xmIndex) { - xmlrpc_value * const itemP = contents[xmIndex]; - xmlrpc_DECREF(itemP); - } - XMLRPC_MEMBLOCK_CLEAN(xmlrpc_value *, &arrayP->_block); -} - - - -int -xmlrpc_array_size(xmlrpc_env * const env, - const xmlrpc_value * const array) { - - int retval; - - /* Suppress a compiler warning about uninitialized variables. */ - retval = 0; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(array); - XMLRPC_TYPE_CHECK(env, array, XMLRPC_TYPE_ARRAY); - - retval = (int)XMLRPC_TYPED_MEM_BLOCK_SIZE(xmlrpc_value*, &array->_block); - - cleanup: - if (env->fault_occurred) - return -1; - else - return retval; -} - - - -void -xmlrpc_array_append_item(xmlrpc_env * const envP, - xmlrpc_value * const arrayP, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(arrayP); - - if (xmlrpc_value_type(arrayP) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not an array"); - else { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); - - XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, &arrayP->_block, size+1); - - if (!envP->fault_occurred) { - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); - xmlrpc_INCREF(valueP); - contents[size] = valueP; - } - } -} - - - -void -xmlrpc_array_read_item(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - unsigned int const xmIndex, - xmlrpc_value ** const valuePP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(arrayP); - XMLRPC_ASSERT_PTR_OK(valuePP); - - if (arrayP->_type != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from " - "a value that is not an array"); - else { - xmlrpc_value ** const contents = - XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &arrayP->_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); - - if (xmIndex >= size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end " - "of %u-item array", xmIndex, (unsigned int)size); - else { - *valuePP = contents[xmIndex]; - xmlrpc_INCREF(*valuePP); - } - } -} - - - -xmlrpc_value * -xmlrpc_array_get_item(xmlrpc_env * const envP, - const xmlrpc_value * const arrayP, - int const xmIndex) { - - xmlrpc_value * valueP; - - if (xmIndex < 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %d is negative."); - else { - xmlrpc_array_read_item(envP, arrayP, xmIndex, &valueP); - - if (!envP->fault_occurred) - xmlrpc_DECREF(valueP); - } - if (envP->fault_occurred) - valueP = NULL; - - return valueP; -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/Utilities/cmxmlrpc/xmlrpc_authcookie.c b/Utilities/cmxmlrpc/xmlrpc_authcookie.c deleted file mode 100644 index cee41478be..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_authcookie.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 2002 by jeff@ourexchange.net. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "xmlrpc.h" - -/* set cookie function */ -void xmlrpc_authcookie_set ( xmlrpc_env *env, - const char *username, - const char *password ) { - char *unencoded; - xmlrpc_mem_block *token; - static char env_buffer[1024]; - const char* block; - - /* Check asserts. */ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(username); - XMLRPC_ASSERT_PTR_OK(password); - - /* Clear out memory. */ - unencoded = (char *) malloc ( sizeof ( char * ) ); - - /* Create unencoded string/hash. */ - sprintf(unencoded, "%s:%s", username, password); - - /* Create encoded string. */ - token = xmlrpc_base64_encode_without_newlines(env, (unsigned char*)unencoded, - strlen(unencoded)); - XMLRPC_FAIL_IF_FAULT(env); - - /* Set HTTP_COOKIE_AUTH to the character representation of the - ** encoded string. */ - block = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, token); - sprintf(env_buffer, "HTTP_COOKIE_AUTH=%s", block); - putenv(env_buffer); - - cleanup: - if (token) xmlrpc_mem_block_free(token); -} - -char *xmlrpc_authcookie ( void ) { - return getenv("HTTP_COOKIE_AUTH"); -} diff --git a/Utilities/cmxmlrpc/xmlrpc_base64.c b/Utilities/cmxmlrpc/xmlrpc_base64.c deleted file mode 100644 index edcb09b538..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_base64.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** There is more copyright information in the bottom half of this file. -** Please see it for more details. */ - - -/*========================================================================= -** XML-RPC Base64 Utilities -**========================================================================= -** This code was swiped from Jack Jansen's code in Python 1.5.2 and -** modified to work with our data types. -*/ - -#include "xmlrpc_config.h" - -#include "xmlrpc.h" - -#define CRLF "\015\012" -#define CR '\015' -#define LF '\012' - - -/*********************************************************** -Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum, -Amsterdam, The Netherlands. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Stichting Mathematisch -Centrum or CWI or Corporation for National Research Initiatives or -CNRI not be used in advertising or publicity pertaining to -distribution of the software without specific, written prior -permission. - -While CWI is the initial source for this software, a modified version -is made available by the Corporation for National Research Initiatives -(CNRI) at the Internet address ftp://ftp.python.org. - -STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH -CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - -******************************************************************/ - -static char table_a2b_base64[] = { - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, /* Note PAD->0 */ - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; - -#define BASE64_PAD '=' -#define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */ -#define BASE64_LINE_SZ 128 /* Buffer size for a single line. */ - -static unsigned char table_b2a_base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static xmlrpc_mem_block * -xmlrpc_base64_encode_internal (xmlrpc_env *env, - unsigned char *bin_data, - size_t bin_len, - int want_newlines) -{ - size_t chunk_start, chunk_left; - unsigned char *ascii_data; - int leftbits; - unsigned char this_ch; - unsigned int leftchar; - xmlrpc_mem_block *output; - unsigned char line_buffer[BASE64_LINE_SZ]; - - /* Create a block to hold our lines when we finish them. */ - output = xmlrpc_mem_block_new(env, 0); - XMLRPC_FAIL_IF_FAULT(env); - - /* Deal with empty data blocks gracefully. Yuck. */ - if (bin_len == 0) { - if (want_newlines) - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, CRLF, 2); - goto cleanup; - } - - /* Process our binary data in line-sized chunks. */ - for (chunk_start=0; chunk_start < bin_len; chunk_start += BASE64_MAXBIN) { - - /* Set up our per-line state. */ - ascii_data = &line_buffer[0]; - chunk_left = bin_len - chunk_start; - if (chunk_left > BASE64_MAXBIN) - chunk_left = BASE64_MAXBIN; - leftbits = 0; - leftchar = 0; - - for(; chunk_left > 0; chunk_left--, bin_data++) { - /* Shift the data into our buffer */ - leftchar = (leftchar << 8) | *bin_data; - leftbits += 8; - - /* See if there are 6-bit groups ready */ - while (leftbits >= 6) { - this_ch = (leftchar >> (leftbits-6)) & 0x3f; - leftbits -= 6; - *ascii_data++ = table_b2a_base64[this_ch]; - } - } - if (leftbits == 2) { - *ascii_data++ = table_b2a_base64[(leftchar&3) << 4]; - *ascii_data++ = BASE64_PAD; - *ascii_data++ = BASE64_PAD; - } else if (leftbits == 4) { - *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; - *ascii_data++ = BASE64_PAD; - } - - /* Append a courtesy CRLF. */ - if (want_newlines) { - *ascii_data++ = CR; - *ascii_data++ = LF; - } - - /* Save our line. */ - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, line_buffer, - ascii_data - &line_buffer[0]); - XMLRPC_FAIL_IF_FAULT(env); - } - - cleanup: - if (env->fault_occurred) { - if (output) - xmlrpc_mem_block_free(output); - return NULL; - } - return output; -} - - -xmlrpc_mem_block * -xmlrpc_base64_encode (xmlrpc_env *env, unsigned char *bin_data, size_t bin_len) -{ - return xmlrpc_base64_encode_internal(env, bin_data, bin_len, 1); -} - - -xmlrpc_mem_block * -xmlrpc_base64_encode_without_newlines (xmlrpc_env *env, - unsigned char *bin_data, - size_t bin_len) -{ - return xmlrpc_base64_encode_internal(env, bin_data, bin_len, 0); -} - - -xmlrpc_mem_block * -xmlrpc_base64_decode (xmlrpc_env *env, - char *ascii_data, - size_t ascii_len) -{ - unsigned char *bin_data; - int leftbits; - unsigned char this_ch; - unsigned int leftchar; - size_t npad; - size_t bin_len, buffer_size; - xmlrpc_mem_block *output; - - /* Create a block to hold our chunks when we finish them. - ** We overestimate the size now, and fix it later. */ - buffer_size = ((ascii_len+3)/4)*3; - output = xmlrpc_mem_block_new(env, buffer_size); - XMLRPC_FAIL_IF_FAULT(env); - - /* Set up our decoder state. */ - leftbits = 0; - leftchar = 0; - npad = 0; - bin_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char, output); - bin_len = 0; - - for( ; ascii_len > 0 ; ascii_len--, ascii_data++ ) { - - /* Skip some punctuation. */ - this_ch = (*ascii_data & 0x7f); - if ( this_ch == '\r' || this_ch == '\n' || this_ch == ' ' ) - continue; - if ( this_ch == BASE64_PAD ) - npad++; - this_ch = table_a2b_base64[(*ascii_data) & 0x7f]; - - /* XXX - We just throw away invalid characters. Is this right? */ - if ( this_ch == (unsigned char) -1 ) continue; - - /* Shift it in on the low end, and see if there's - ** a byte ready for output. */ - leftchar = (leftchar << 6) | (this_ch); - leftbits += 6; - if ( leftbits >= 8 ) { - leftbits -= 8; - XMLRPC_ASSERT(bin_len < buffer_size); - *bin_data++ = (leftchar >> leftbits) & 0xFF; - leftchar &= ((1 << leftbits) - 1); - bin_len++; - } - } - - /* Check that no bits are left. */ - if ( leftbits ) - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, "Incorrect Base64 padding"); - - /* Check to make sure we have a sane amount of padding. */ - if (npad > bin_len || npad > 2) - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, "Malformed Base64 data"); - - /* Remove any padding and set the correct size. */ - bin_len -= npad; - XMLRPC_TYPED_MEM_BLOCK_RESIZE(char, env, output, bin_len); - XMLRPC_ASSERT(!env->fault_occurred); - - cleanup: - if (env->fault_occurred) { - if (output) - xmlrpc_mem_block_free(output); - return NULL; - } - return output; -} diff --git a/Utilities/cmxmlrpc/xmlrpc_cgi.c b/Utilities/cmxmlrpc/xmlrpc_cgi.c deleted file mode 100644 index e3a8b42ffb..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_cgi.c +++ /dev/null @@ -1,295 +0,0 @@ -/* Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#include "xmlrpc_config.h" - -#include -#include -#include - -/* Windows NT stdout binary mode fix. */ -#ifdef _WIN32 -#include -#include -#endif - -#include "xmlrpc.h" -#include "xmlrpc_server.h" -#include "xmlrpc_cgi.h" - - -/*========================================================================= -** Output Routines -**========================================================================= -** These routines send various kinds of responses to the server. -*/ - -static void send_xml (char *xml_data, size_t xml_len) -{ - /* Send our CGI headers back to the server. - ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under - ** really weird circumstances. */ - fprintf(stdout, "Status: 200 OK\n"); - /* Handle authentication cookie being sent back. */ - if (getenv("HTTP_COOKIE_AUTH") != NULL) - fprintf(stdout, "Set-Cookie: auth=%s\n", getenv("HTTP_COOKIE_AUTH")); - fprintf(stdout, "Content-type: text/xml; charset=\"utf-8\"\n"); - fprintf(stdout, "Content-length: %ld\n\n", (unsigned long) xml_len); - - /* Blast out our data. */ - fwrite(xml_data, sizeof(char), xml_len, stdout); -} - -static void send_error (int code, char *message, xmlrpc_env *env) -{ - /* Send an error header. */ - fprintf(stdout, "Status: %d %s\n", code, message); - fprintf(stdout, "Content-type: text/html\n\n"); - - /* Send an error message. */ - fprintf(stdout, "%d %s\n", code, message); - fprintf(stdout, "

%d %s

\n", code, message); - fprintf(stdout, "

An error occurred processing your request.

\n"); - - /* Print out the XML-RPC fault, if present. */ - if (env && env->fault_occurred) - fprintf(stdout, "

XML-RPC Fault #%d: %s

\n", - env->fault_code, env->fault_string); -} - - -/*========================================================================= -** die_if_fault_occurred -**========================================================================= -** Certain kinds of errors aren't worth the trouble of generating -** an XML-RPC fault. For these, we just send status 500 to our web server -** and log the fault to our server log. -*/ - -static void die_if_fault_occurred (xmlrpc_env *env) -{ - if (env->fault_occurred) { - fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", - env->fault_string, env->fault_code); - send_error(500, "Internal Server Error", env); - exit(1); - } -} - - -/*========================================================================= -** Initialization, Cleanup & Method Registry -**========================================================================= -** These are all related, so we group them together. -*/ - -static xmlrpc_registry *registry; - -void xmlrpc_cgi_init (int flags ATTR_UNUSED) -{ - xmlrpc_env env; - - xmlrpc_env_init(&env); - registry = xmlrpc_registry_new(&env); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); - -#ifdef _WIN32 - /* Fix from Jeff Stewart: NT opens stdin and stdout in text mode - ** by default, badly confusing our length calculations. So we need - ** to set these file handles to binary. */ - _setmode(_fileno(stdout), _O_BINARY); - _setmode(_fileno(stdin), _O_BINARY); -#endif -} - -void xmlrpc_cgi_cleanup (void) -{ - xmlrpc_registry_free(registry); -} - -xmlrpc_registry *xmlrpc_cgi_registry (void) -{ - return registry; -} - -void xmlrpc_cgi_add_method (char *method_name, - xmlrpc_method method, - void *user_data) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method(&env, registry, NULL, method_name, - method, user_data); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - -extern void -xmlrpc_cgi_add_method_w_doc (char *method_name, - xmlrpc_method method, - void *user_data, - char *signature, - char *help) -{ - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method_w_doc(&env, registry, NULL, method_name, - method, user_data, signature, help); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - - -/*========================================================================= -** get_body -**========================================================================= -** Slurp the body of the request into an xmlrpc_mem_block. -*/ - -static xmlrpc_mem_block *get_body (xmlrpc_env *env, size_t length) -{ - xmlrpc_mem_block *result; - char *contents; - size_t count; - - XMLRPC_ASSERT_ENV_OK(env); - - /* Error-handling preconditions. */ - result = NULL; - - /* XXX - Puke if length is too big. */ - - /* Allocate our memory block. */ - result = xmlrpc_mem_block_new(env, length); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, result); - - /* Get our data off the network. - ** XXX - Coercing 'size_t' to 'unsigned long' might be unsafe under - ** really weird circumstances. */ - count = fread(contents, sizeof(char), length, stdin); - if (count < length) - XMLRPC_FAIL2(env, XMLRPC_INTERNAL_ERROR, - "Expected %ld bytes, received %ld", - (unsigned long) length, (unsigned long) count); - - cleanup: - if (env->fault_occurred) { - if (result) - xmlrpc_mem_block_free(result); - return NULL; - } - return result; -} - - -/*========================================================================= -** xmlrpc_cgi_process_call -**========================================================================= -** Parse the incoming XML-RPC call, find the right method, call it, and -** serialize our response. -*/ - -void xmlrpc_cgi_process_call (void) -{ - xmlrpc_env env; - char *method, *type, *length_str; - int length; - xmlrpc_mem_block *input, *output; - char *input_data, *output_data; - size_t input_size, output_size; - int code; - char *message; - - /* Error-handling preconditions. */ - xmlrpc_env_init(&env); - input = output = NULL; - - /* Set up a default error message. */ - code = 500; message = "Internal Server Error"; - - /* Get our HTTP information from the environment. */ - method = getenv("REQUEST_METHOD"); - type = getenv("CONTENT_TYPE"); - length_str = getenv("CONTENT_LENGTH"); - - /* Perform some sanity checks. */ - if (!method || 0 != strcmp(method, "POST")) { - code = 405; message = "Method Not Allowed"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Expected HTTP method POST"); - } - if (!type || 0 != strcmp(type, "text/xml")) { - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Expected text/xml content"); - } - if (!length_str) { - code = 411; message = "Length Required"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length required"); - } - - /* Get our content length. */ - length = atoi(length_str); - if (length <= 0) { - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_INTERNAL_ERROR, "Content-length must be > 0"); - } - - /* SECURITY: Make sure our content length is legal. - ** XXX - We can cast 'input_len' because we know it's >= 0, yes? */ - if ((size_t) length > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) { - code = 400; message = "Bad Request"; - XMLRPC_FAIL(&env, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large"); - } - - /* Get our body. */ - input = get_body(&env, length); - XMLRPC_FAIL_IF_FAULT(&env); - input_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, input); - input_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, input); - - /* Process our call. */ - output = xmlrpc_registry_process_call(&env, registry, NULL, - input_data, input_size); - XMLRPC_FAIL_IF_FAULT(&env); - output_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); - output_size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output); - - /* Send our data. */ - send_xml(output_data, output_size); - - cleanup: - if (input) - xmlrpc_mem_block_free(input); - if (output) - xmlrpc_mem_block_free(output); - - if (env.fault_occurred) - send_error(code, message, &env); - - xmlrpc_env_clean(&env); -} diff --git a/Utilities/cmxmlrpc/xmlrpc_cgi.h b/Utilities/cmxmlrpc/xmlrpc_cgi.h deleted file mode 100644 index 0b9fc6d61b..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_cgi.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifndef _XMLRPC_CGI_H_ -#define _XMLRPC_CGI_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/*========================================================================= -** XML-RPC CGI Server -**========================================================================= -** A simple XML-RPC server based on the Common Gateway Interface. -*/ - -#define XMLRPC_CGI_NO_FLAGS (0) - -/* Initialize the CGI server library. */ -extern void -xmlrpc_cgi_init (int flags); - -/* Fetch the internal registry, if you happen to need it. */ -extern xmlrpc_registry * -xmlrpc_cgi_registry (void); - -/* Register a new method. */ -extern void -xmlrpc_cgi_add_method (char *method_name, - xmlrpc_method method, - void *user_data); - -/* As above, but provide documentation (see xmlrpc_registry_add_method_w_doc -** for more information). You should really use this one. */ -extern void -xmlrpc_cgi_add_method_w_doc (char *method_name, - xmlrpc_method method, - void *user_data, - char *signature, - char *help); - -/* Parse the XML-RPC call, invoke the appropriate method, and send the -** response over the network. In future releases, we reserve the right to -** time out when reading data. For now, we rely on the webserver to blow us -** away. */ -extern void -xmlrpc_cgi_process_call (void); - -/* Clean up any internal data structures before exiting. */ -extern void -xmlrpc_cgi_cleanup (void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _XMLRPC_CGI_H_ */ diff --git a/Utilities/cmxmlrpc/xmlrpc_client.c b/Utilities/cmxmlrpc/xmlrpc_client.c deleted file mode 100644 index a5ad65ceaf..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_client.c +++ /dev/null @@ -1,977 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#undef PACKAGE -#undef VERSION - -#include -#include -#include -#include -#include -#include - -#include "bool.h" -#include "mallocvar.h" -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_client.h" -#include "xmlrpc_client_int.h" -/* transport_config.h defines XMLRPC_DEFAULT_TRANSPORT, - MUST_BUILD_WININET_CLIENT, MUST_BUILD_CURL_CLIENT, - MUST_BUILD_LIBWWW_CLIENT -*/ -#include "transport_config.h" - -#if MUST_BUILD_WININET_CLIENT -#include "xmlrpc_wininet_transport.h" -#endif -#if MUST_BUILD_CURL_CLIENT -#include "xmlrpc_curl_transport.h" -#endif -#if MUST_BUILD_LIBWWW_CLIENT -#include "xmlrpc_libwww_transport.h" -#endif - -struct xmlrpc_client { -/*---------------------------------------------------------------------------- - This represents a client object. ------------------------------------------------------------------------------*/ - struct clientTransport * transportP; -}; - - - -typedef struct call_info -{ - /* These fields are used when performing asynchronous calls. - ** The _asynch_data_holder contains server_url, method_name and - ** param_array, so it's the only thing we need to free. */ - xmlrpc_value *_asynch_data_holder; - char *server_url; - char *method_name; - xmlrpc_value *param_array; - xmlrpc_response_handler callback; - void *user_data; - - /* The serialized XML data passed to this call. We keep this around - ** for use by our source_anchor field. */ - xmlrpc_mem_block *serialized_xml; -} call_info; - -static bool clientInitialized = FALSE; - -/*========================================================================= -** Initialization and Shutdown -**========================================================================= -*/ - -static struct clientTransportOps clientTransportOps; - -static struct xmlrpc_client client; - /* Some day, we need to make this dynamically allocated, so there can - be more than one client per program and just generally to provide - a cleaner interface. - */ - -extern void -xmlrpc_client_init(int const flags, - const char * const appname, - const char * const appversion) { - - struct xmlrpc_clientparms clientparms; - - /* As our interface does not allow for failure, we just fail silently ! */ - - xmlrpc_env env; - xmlrpc_env_init(&env); - - clientparms.transport = XMLRPC_DEFAULT_TRANSPORT; - - xmlrpc_client_init2(&env, flags, - appname, appversion, - &clientparms, XMLRPC_CPSIZE(transport)); - - xmlrpc_env_clean(&env); -} - - - -const char * -xmlrpc_client_get_default_transport(xmlrpc_env * const env ATTR_UNUSED) { - - return XMLRPC_DEFAULT_TRANSPORT; -} - - - -static void -setupTransport(xmlrpc_env * const envP, - const char * const transportName) { - - if (FALSE) { - } -#if MUST_BUILD_WININET_CLIENT - else if (strcmp(transportName, "wininet") == 0) - clientTransportOps = xmlrpc_wininet_transport_ops; -#endif -#if MUST_BUILD_CURL_CLIENT - else if (strcmp(transportName, "curl") == 0) - clientTransportOps = xmlrpc_curl_transport_ops; - else if (strcmp(transportName, "libcurl") == 0) - clientTransportOps = xmlrpc_curl_transport_ops; -#endif -#if MUST_BUILD_LIBWWW_CLIENT - else if (strcmp(transportName, "libwww") == 0) - clientTransportOps = xmlrpc_libwww_transport_ops; -#endif - else - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unrecognized XML transport name '%s'", transportName); -} - - - -void -xmlrpc_client_init2(xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - struct xmlrpc_clientparms * const clientparmsP, - unsigned int const parm_size) { - - if (clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has already been initialized " - "(need to call xmlrpc_client_cleanup() before you can " - "reinitialize)."); - else { - const char * transportName; - - if (parm_size < XMLRPC_CPSIZE(transport) || - clientparmsP->transport == NULL) { - /* He didn't specify a transport. Use the default */ - transportName = xmlrpc_client_get_default_transport(envP); - } else - transportName = clientparmsP->transport; - - if (!envP->fault_occurred) { - setupTransport(envP, transportName); - if (!envP->fault_occurred) { - clientTransportOps.create(envP, flags, appname, appversion, - &client.transportP); - if (!envP->fault_occurred) - clientInitialized = TRUE; - } - } - } -} - - - -void -xmlrpc_client_cleanup() { - - XMLRPC_ASSERT(clientInitialized); - - clientTransportOps.destroy(client.transportP); - - clientInitialized = FALSE; -} - - - -static void -call_info_free(call_info * const callInfoP) { - - /* Assume the worst.. That only parts of the call_info are valid. */ - - XMLRPC_ASSERT_PTR_OK(callInfoP); - - /* If this has been allocated, we're responsible for destroying it. */ - if (callInfoP->_asynch_data_holder) - xmlrpc_DECREF(callInfoP->_asynch_data_holder); - - /* Now we can blow away the XML data. */ - if (callInfoP->serialized_xml) - xmlrpc_mem_block_free(callInfoP->serialized_xml); - - free(callInfoP); -} - - - -static void -call_info_new(xmlrpc_env * const envP, - xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_value * const argP, - call_info ** const callInfoPP) { -/*---------------------------------------------------------------------------- - Create a call_info object. A call_info object represents an XML-RPC - call. ------------------------------------------------------------------------------*/ - call_info * callInfoP; - - XMLRPC_ASSERT_PTR_OK(argP); - XMLRPC_ASSERT_PTR_OK(callInfoPP); - - if (method_name == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "method name argument is NULL pointer"); - else if (server == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "server info argument is NULL pointer"); - else { - MALLOCVAR(callInfoP); - if (callInfoP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_call_info"); - else { - xmlrpc_mem_block * callXmlP; - - /* Clear contents. */ - memset(callInfoP, 0, sizeof(*callInfoP)); - - /* Make the XML for our call */ - callXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - xmlrpc_serialize_call(envP, callXmlP, method_name, argP); - if (!envP->fault_occurred) { - xmlrpc_traceXml("XML-RPC CALL", - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP), - (unsigned int)XMLRPC_MEMBLOCK_SIZE(char, callXmlP)); - - callInfoP->serialized_xml = callXmlP; - - *callInfoPP = callInfoP; - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, callXmlP); - } - if (envP->fault_occurred) - free(callInfoP); - } - } -} - - - -static void -clientCallServerParams(xmlrpc_env * const envP, - struct clientTransport * const transportP, - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - call_info * callInfoP; - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else { - call_info_new(envP, serverP, methodName, paramArrayP, &callInfoP); - if (!envP->fault_occurred) { - xmlrpc_mem_block * respXmlP; - - clientTransportOps.call(envP, transportP, serverP, - callInfoP->serialized_xml, callInfoP, - &respXmlP); - if (!envP->fault_occurred) { - xmlrpc_traceXml("XML-RPC RESPONSE", - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - (unsigned int)XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); - - *resultPP = xmlrpc_parse_response( - envP, - XMLRPC_MEMBLOCK_CONTENTS(char, respXmlP), - XMLRPC_MEMBLOCK_SIZE(char, respXmlP)); - XMLRPC_MEMBLOCK_FREE(char, respXmlP); - } - call_info_free(callInfoP); - } - } -} - - - -xmlrpc_value * -xmlrpc_client_call_params(xmlrpc_env * const envP, - const char * const serverUrl, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - xmlrpc_value *retval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverUrl); - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else { - xmlrpc_server_info * serverP; - - /* Build a server info object and make our call. */ - serverP = xmlrpc_server_info_new(envP, serverUrl); - if (!envP->fault_occurred) { - clientCallServerParams(envP, client.transportP, serverP, - methodName, paramArrayP, - &retval); - - xmlrpc_server_info_free(serverP); - } - } - - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(retval); - - return retval; -} - - - -static xmlrpc_value * -xmlrpc_client_call_va(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - va_list args) { - - xmlrpc_value * argP; - xmlrpc_value * retval = 0; - xmlrpc_env argenv; - const char * suffix; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument value. */ - xmlrpc_env_init(&argenv); - xmlrpc_build_value_va(&argenv, format, args, &argP, &suffix); - if (argenv.fault_occurred) { - xmlrpc_env_set_fault_formatted( - envP, argenv.fault_code, "Invalid RPC arguments. " - "The format argument must indicate a single array, and the " - "following arguments must correspond to that format argument. " - "The failure is: %s", - argenv.fault_string); - xmlrpc_env_clean(&argenv); - } else { - XMLRPC_ASSERT_VALUE_OK(argP); - - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - /* Perform the actual XML-RPC call. */ - retval = xmlrpc_client_call_params( - envP, server_url, method_name, argP); - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(retval); - } - xmlrpc_DECREF(argP); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_client_call(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - ...) { - - xmlrpc_value * result; - va_list args; - - va_start(args, format); - result = xmlrpc_client_call_va(envP, server_url, - method_name, format, args); - va_end(args); - - return result; -} - - - -xmlrpc_value * -xmlrpc_client_call_server(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - const char * const methodName, - const char * const format, - ...) { - - va_list args; - xmlrpc_value * paramArrayP; - xmlrpc_value * retval; - const char * suffix; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument */ - va_start(args, format); - xmlrpc_build_value_va(envP, format, args, ¶mArrayP, &suffix); - va_end(args); - - if (!envP->fault_occurred) { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else - clientCallServerParams(envP, client.transportP, serverP, - methodName, paramArrayP, - &retval); - - xmlrpc_DECREF(paramArrayP); - } - return retval; -} - - -void -xmlrpc_client_event_loop_finish_asynch(void) { - XMLRPC_ASSERT(clientInitialized); - clientTransportOps.finish_asynch(client.transportP, timeout_no, 0); -} - - - -void -xmlrpc_client_event_loop_finish_asynch_timeout(timeout_t const timeout) { - XMLRPC_ASSERT(clientInitialized); - clientTransportOps.finish_asynch(client.transportP, timeout_yes, timeout); -} - - - -static void -call_info_set_asynch_data(xmlrpc_env * const env, - call_info * const info, - const char * const server_url, - const char * const method_name, - xmlrpc_value * const argP, - xmlrpc_response_handler callback, - void * const user_data) { - - xmlrpc_value *holder; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(info); - XMLRPC_ASSERT(info->_asynch_data_holder == NULL); - XMLRPC_ASSERT_PTR_OK(server_url); - XMLRPC_ASSERT_PTR_OK(method_name); - XMLRPC_ASSERT_VALUE_OK(argP); - - /* Install our callback and user_data. - ** (We're not responsible for destroying the user_data.) */ - info->callback = callback; - info->user_data = user_data; - - /* Build an XML-RPC data structure to hold our other data. This makes - ** copies of server_url and method_name, and increments the reference - ** to the argument *argP. */ - holder = xmlrpc_build_value(env, "(ssV)", - server_url, method_name, argP); - XMLRPC_FAIL_IF_FAULT(env); - - /* Parse the newly-allocated structure into our public member variables. - ** This doesn't make any new references, so we can dispose of the whole - ** thing by DECREF'ing the one master reference. Nifty, huh? */ - xmlrpc_parse_value(env, holder, "(ssV)", - &info->server_url, - &info->method_name, - &info->param_array); - XMLRPC_FAIL_IF_FAULT(env); - - /* Hand over ownership of the holder to the call_info struct. */ - info->_asynch_data_holder = holder; - holder = NULL; - - cleanup: - if (env->fault_occurred) { - if (holder) - xmlrpc_DECREF(holder); - } -} - -/*========================================================================= -** xmlrpc_server_info -**========================================================================= -*/ - -xmlrpc_server_info * -xmlrpc_server_info_new (xmlrpc_env * const env, - const char * const server_url) { - - xmlrpc_server_info *server; - char *url_copy; - - /* Error-handling preconditions. */ - url_copy = NULL; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(server_url); - - /* Allocate our memory blocks. */ - server = (xmlrpc_server_info*) malloc(sizeof(xmlrpc_server_info)); - XMLRPC_FAIL_IF_NULL(server, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_server_info"); - memset(server, 0, sizeof(xmlrpc_server_info)); - url_copy = (char*) malloc(strlen(server_url) + 1); - XMLRPC_FAIL_IF_NULL(url_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for server URL"); - - /* Build our object. */ - strcpy(url_copy, server_url); - server->_server_url = url_copy; - server->_http_basic_auth = NULL; - - cleanup: - if (env->fault_occurred) { - if (url_copy) - free(url_copy); - if (server) - free(server); - return NULL; - } - return server; -} - -xmlrpc_server_info * xmlrpc_server_info_copy(xmlrpc_env *env, - xmlrpc_server_info *aserver) -{ - xmlrpc_server_info *server; - char *url_copy, *auth_copy; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(aserver); - - /* Error-handling preconditions. */ - url_copy = NULL; - auth_copy = NULL; - - /* Allocate our memory blocks. */ - server = (xmlrpc_server_info*) malloc(sizeof(xmlrpc_server_info)); - XMLRPC_FAIL_IF_NULL(server, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for xmlrpc_server_info"); - url_copy = (char*) malloc(strlen(aserver->_server_url) + 1); - XMLRPC_FAIL_IF_NULL(url_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for server URL"); - auth_copy = (char*) malloc(strlen(aserver->_http_basic_auth) + 1); - XMLRPC_FAIL_IF_NULL(auth_copy, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for authentication info"); - - /* Build our object. */ - strcpy(url_copy, aserver->_server_url); - server->_server_url = url_copy; - strcpy(auth_copy, aserver->_http_basic_auth); - server->_http_basic_auth = auth_copy; - - cleanup: - if (env->fault_occurred) { - if (url_copy) - free(url_copy); - if (auth_copy) - free(auth_copy); - if (server) - free(server); - return NULL; - } - return server; - -} - -void xmlrpc_server_info_free (xmlrpc_server_info *server) -{ - XMLRPC_ASSERT_PTR_OK(server); - XMLRPC_ASSERT(server->_server_url != XMLRPC_BAD_POINTER); - - if (server->_http_basic_auth) - free(server->_http_basic_auth); - free(server->_server_url); - server->_server_url = XMLRPC_BAD_POINTER; - free(server); -} - -/*========================================================================= -** xmlrpc_client_call_asynch -**========================================================================= -*/ - -void -xmlrpc_client_call_asynch(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - va_list args; - xmlrpc_value * paramArrayP; - const char * suffix; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverUrl); - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our argument array. */ - va_start(args, format); - xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); - va_end(args); - if (env.fault_occurred) { - /* Unfortunately, we have no way to return an error and the - regular callback for a failed RPC is designed to have the - parameter array passed to it. This was probably an oversight - of the original asynch design, but now we have to be as - backward compatible as possible, so we do this: - */ - (*callback)(serverUrl, methodName, NULL, userData, &env, NULL); - } else { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - xmlrpc_server_info * serverP; - serverP = xmlrpc_server_info_new(&env, serverUrl); - if (!env.fault_occurred) { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, - paramArrayP); - } - xmlrpc_server_info_free(serverP); - } - if (env.fault_occurred) - (*callback)(serverUrl, methodName, paramArrayP, userData, - &env, NULL); - xmlrpc_DECREF(paramArrayP); - } - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_asynch_params(const char * const serverUrl, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - xmlrpc_value * const paramArrayP) { - - xmlrpc_env env; - xmlrpc_server_info *serverP; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverUrl); - - serverP = xmlrpc_server_info_new(&env, serverUrl); - if (!env.fault_occurred) { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, paramArrayP); - - xmlrpc_server_info_free(serverP); - } - - if (env.fault_occurred) - /* We have no way to return failure; we report the failure - as it happened after we successfully started the RPC. - */ - (*callback)(serverUrl, methodName, paramArrayP, userData, - &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_client_call_server_asynch(xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler callback, - void * const userData, - const char * const format, - ...) { - - xmlrpc_env env; - va_list args; - xmlrpc_value * paramArrayP; - const char * suffix; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(format); - - /* Build our parameter array. */ - va_start(args, format); - xmlrpc_build_value_va(&env, format, args, ¶mArrayP, &suffix); - va_end(args); - if (env.fault_occurred) { - /* Unfortunately, we have no way to return an error and the - regular callback for a failed RPC is designed to have the - parameter array passed to it. This was probably an oversight - of the original asynch design, but now we have to be as - backward compatible as possible, so we do this: - */ - (*callback)(serverP->_server_url, methodName, NULL, userData, - &env, NULL); - } else { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - else { - xmlrpc_client_call_server_asynch_params( - serverP, methodName, callback, userData, paramArrayP); - } - xmlrpc_DECREF(paramArrayP); - } - - if (env.fault_occurred) - (*callback)(serverP->_server_url, methodName, paramArrayP, userData, - &env, NULL); - - xmlrpc_env_clean(&env); -} - - - -static void -asynchComplete(call_info * const callInfoP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_env const transportEnv) { -/*---------------------------------------------------------------------------- - Complete an asynchronous XML-RPC call request. - - This includes calling the user's RPC completion routine. - - 'transportEnv' describes the an error that the transport - encountered in processing the call. If the transport successfully - sent the call to the server and processed the response but the - server failed the call, 'transportEnv' indicates no error, and the - response in *callInfoP might very well indicate that the server - failed the request. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - xmlrpc_value * responseP = 0; - - xmlrpc_env_init(&env); - - if (transportEnv.fault_occurred) - xmlrpc_env_set_fault_formatted( - &env, transportEnv.fault_code, - "Client transport failed to execute the RPC. %s", - transportEnv.fault_string); - - if (!env.fault_occurred) - responseP = xmlrpc_parse_response( - &env, - XMLRPC_MEMBLOCK_CONTENTS(char, responseXmlP), - XMLRPC_MEMBLOCK_SIZE(char, responseXmlP)); - - /* Call the user's callback function with the result */ - (*callInfoP->callback)(callInfoP->server_url, - callInfoP->method_name, - callInfoP->param_array, - callInfoP->user_data, &env, responseP); - - if (!env.fault_occurred) - xmlrpc_DECREF(responseP); - - call_info_free(callInfoP); - - xmlrpc_env_clean(&env); -} - - - -static void -sendRequest(xmlrpc_env * const envP, - struct clientTransport * const transportP, - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const argP) { - - call_info * callInfoP; - - call_info_new(envP, serverP, methodName, argP, &callInfoP); - if (!envP->fault_occurred) { - call_info_set_asynch_data(envP, callInfoP, - serverP->_server_url, methodName, - argP, responseHandler, userData); - if (!envP->fault_occurred) - clientTransportOps.send_request( - envP, transportP, serverP, callInfoP->serialized_xml, - &asynchComplete, callInfoP); - - if (envP->fault_occurred) - call_info_free(callInfoP); - else { - /* asynchComplete() will free *callInfoP */ - } - } - if (envP->fault_occurred) { - /* Transport did not start the call. Report the call complete - (with error) now. - */ - (*responseHandler)(serverP->_server_url, methodName, argP, userData, - envP, NULL); - } else { - /* The transport will call *responseHandler() when it has completed - the call - */ - } -} - - - -void -xmlrpc_client_call_server_asynch_params( - xmlrpc_server_info * const serverP, - const char * const methodName, - xmlrpc_response_handler responseHandler, - void * const userData, - xmlrpc_value * const argP) { - xmlrpc_env env; - - xmlrpc_env_init(&env); - - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(methodName); - XMLRPC_ASSERT_PTR_OK(responseHandler); - XMLRPC_ASSERT_VALUE_OK(argP); - - if (!clientInitialized) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_INTERNAL_ERROR, - "Xmlrpc-c client instance has not been initialized " - "(need to call xmlrpc_client_init2())."); - else - sendRequest(&env, client.transportP, serverP, - methodName, responseHandler, userData, - argP); - - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - const char * const username, - const char * const password) { - - size_t username_len, password_len, raw_token_len; - char *raw_token; - xmlrpc_mem_block *token; - char *token_data, *auth_type, *auth_header; - size_t token_len, auth_type_len, auth_header_len; - - /* Error-handling preconditions. */ - token = NULL; - auth_header = NULL; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(username); - XMLRPC_ASSERT_PTR_OK(password); - - /* Calculate some lengths. */ - username_len = strlen(username); - password_len = strlen(password); - raw_token_len = username_len + password_len + 1; - - /* Build a raw token of the form 'username:password'. */ - raw_token = (char*) malloc(raw_token_len + 1); - XMLRPC_FAIL_IF_NULL(raw_token, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for auth token"); - strcpy(raw_token, username); - raw_token[username_len] = ':'; - strcpy(&raw_token[username_len + 1], password); - - /* Encode our raw token using Base64. */ - token = xmlrpc_base64_encode_without_newlines(envP, - (unsigned char*) raw_token, - raw_token_len); - XMLRPC_FAIL_IF_FAULT(envP); - token_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, token); - token_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, token); - - /* Build our actual header value. (I hate string processing in C.) */ - auth_type = "Basic "; - auth_type_len = strlen(auth_type); - auth_header_len = auth_type_len + token_len; - auth_header = (char*) malloc(auth_header_len + 1); - XMLRPC_FAIL_IF_NULL(auth_header, envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for auth header"); - memcpy(auth_header, auth_type, auth_type_len); - memcpy(&auth_header[auth_type_len], token_data, token_len); - auth_header[auth_header_len] = '\0'; - - /* Clean up any pre-existing authentication information, and install - ** the new value. */ - if (serverP->_http_basic_auth) - free(serverP->_http_basic_auth); - serverP->_http_basic_auth = auth_header; - - cleanup: - if (raw_token) - free(raw_token); - if (token) - xmlrpc_mem_block_free(token); - if (envP->fault_occurred) { - if (auth_header) - free(auth_header); - } -} - diff --git a/Utilities/cmxmlrpc/xmlrpc_client.h b/Utilities/cmxmlrpc/xmlrpc_client.h deleted file mode 100644 index acb89b1111..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_client.h +++ /dev/null @@ -1,261 +0,0 @@ -/*============================================================================ - xmlrpc_client.h -============================================================================== - This header file defines the interface between xmlrpc.c and its users, - related to clients. - - Copyright information is at the end of the file. -============================================================================*/ - -#ifndef _XMLRPC_CLIENT_H_ -#define _XMLRPC_CLIENT_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/*========================================================================= -** Initialization and Shutdown -**========================================================================= -** These routines initialize and terminate the XML-RPC client. If you're -** already using libwww on your own, you can pass -** XMLRPC_CLIENT_SKIP_LIBWWW_INIT to avoid initializing it twice. -*/ - -#define XMLRPC_CLIENT_NO_FLAGS (0) -#define XMLRPC_CLIENT_SKIP_LIBWWW_INIT (1) - -extern void -xmlrpc_client_init(int const flags, - const char * const appname, - const char * const appversion); - -struct xmlrpc_clientparms { - const char * transport; -}; - -#define XMLRPC_CP_MEMBER_OFFSET(mbrname) \ - ((unsigned long)(char*)&((struct xmlrpc_clientparms *)0)->mbrname) -#define XMLRPC_CP_MEMBER_SIZE(mbrname) \ - sizeof(((struct xmlrpc_clientparms *)0)->mbrname) -#define XMLRPC_CPSIZE(mbrname) \ - (XMLRPC_CP_MEMBER_OFFSET(mbrname) + XMLRPC_CP_MEMBER_SIZE(mbrname)) - -/* XMLRPC_CPSIZE(xyz) is the minimum size a struct xmlrpc_clientparms - must be to include the 'xyz' member. This is essential to forward and - backward compatbility, as new members will be added to the end of the - struct in future releases. This is how the callee knows whether or - not the caller is new enough to have supplied a certain parameter. -*/ - -void -xmlrpc_client_init2(xmlrpc_env * const env, - int const flags, - const char * const appname, - const char * const appversion, - struct xmlrpc_clientparms * const clientparms, - unsigned int const parm_size); - -extern void -xmlrpc_client_cleanup(void); - -const char * -xmlrpc_client_get_default_transport(xmlrpc_env * const env); - -/*========================================================================= -** Required for both internal and external development. -**========================================================================= -*/ -/* A callback function to handle the response to an asynchronous call. -** If 'fault->fault_occurred' is true, then response will be NULL. All -** arguments except 'user_data' will be deallocated internally; please do -** not free any of them yourself. -** WARNING: param_array may (or may not) be NULL if fault->fault_occurred -** is true, and you set up the call using xmlrpc_client_call_asynch. -** WARNING: If asynchronous calls are still pending when the library is -** shut down, your handler may (or may not) be called with a fault. */ -typedef void (*xmlrpc_response_handler) (const char *server_url, - const char *method_name, - xmlrpc_value *param_array, - void *user_data, - xmlrpc_env *fault, - xmlrpc_value *result); - - -/*========================================================================= -** xmlrpc_server_info -**========================================================================= -** We normally refer to servers by URL. But sometimes we need to do extra -** setup for particular servers. In that case, we can create an -** xmlrpc_server_info object, configure it in various ways, and call the -** remote server. -** -** (This interface is also designed to discourage further multiplication -** of xmlrpc_client_call APIs. We have enough of those already. Please -** add future options and flags using xmlrpc_server_info.) -*/ - -typedef struct _xmlrpc_server_info xmlrpc_server_info; - -/* Create a new server info record, pointing to the specified server. */ -xmlrpc_server_info * -xmlrpc_server_info_new(xmlrpc_env * const env, - const char * const server_url); - -/* Create a new server info record, with a copy of the old server. */ -extern xmlrpc_server_info * -xmlrpc_server_info_copy(xmlrpc_env *env, xmlrpc_server_info *src_server); - -/* Delete a server info record. */ -extern void -xmlrpc_server_info_free (xmlrpc_server_info *server); - -/* We support rudimentary basic authentication. This lets us talk to Zope -** servers and similar critters. When called, this routine makes a copy -** of all the authentication information and passes it to future requests. -** Only the most-recently-set authentication information is used. -** (In general, you shouldn't write XML-RPC servers which require this -** kind of authentication--it confuses many client implementations.) -** If we fail, leave the xmlrpc_server_info record unchanged. */ -void -xmlrpc_server_info_set_basic_auth(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - const char * const username, - const char * const password); - - -/*========================================================================= -** xmlrpc_client_call -**========================================================================= -** A synchronous XML-RPC client. Do not attempt to call any of these -** functions from inside an asynchronous callback! -*/ - -xmlrpc_value * -xmlrpc_client_call(xmlrpc_env * const envP, - const char * const server_url, - const char * const method_name, - const char * const format, - ...); - -xmlrpc_value * -xmlrpc_client_call_params (xmlrpc_env * const env, - const char * const server_url, - const char * const method_name, - xmlrpc_value * const param_array); - -xmlrpc_value * -xmlrpc_client_call_server(xmlrpc_env * const envP, - xmlrpc_server_info * const server, - const char * const method_name, - const char * const format, - ...); - -extern xmlrpc_value * -xmlrpc_client_call_server_params (xmlrpc_env *env, - xmlrpc_server_info *server, - char *method_name, - xmlrpc_value *param_array); - - -/*========================================================================= -** xmlrpc_client_call_asynch -**========================================================================= -** An asynchronous XML-RPC client. -*/ - -/* Make an asynchronous XML-RPC call. We make internal copies of all -** arguments except user_data, so you can deallocate them safely as soon -** as you return. Errors will be passed to the callback. You will need -** to run the event loop somehow; see below. -** WARNING: If an error occurs while building the argument, the -** response handler will be called with a NULL param_array. */ -void -xmlrpc_client_call_asynch(const char * const server_url, - const char * const method_name, - xmlrpc_response_handler callback, - void * const user_data, - const char * const format, - ...); - -/* As above, but use an xmlrpc_server_info object. The server object can be -** safely destroyed as soon as this function returns. */ -void -xmlrpc_client_call_server_asynch(xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_response_handler callback, - void * const user_data, - const char * const format, - ...); - -/* As above, but the parameter list is supplied as an xmlrpc_value -** containing an array. -*/ -void -xmlrpc_client_call_asynch_params(const char * const server_url, - const char * const method_name, - xmlrpc_response_handler callback, - void * const user_data, - xmlrpc_value * const paramArrayP); - -/* As above, but use an xmlrpc_server_info object. The server object can be -** safely destroyed as soon as this function returns. */ -void -xmlrpc_client_call_server_asynch_params( - xmlrpc_server_info * const server, - const char * const method_name, - xmlrpc_response_handler callback, - void * const user_data, - xmlrpc_value * const paramArrayP); - -/*========================================================================= -** Event Loop Interface -**========================================================================= -** These functions can be used to run the XML-RPC event loop. If you -** don't like these, you can also run the libwww event loop directly. -*/ - -/* Finish all outstanding asynchronous calls. Alternatively, the loop -** will exit if someone calls xmlrpc_client_event_loop_end. */ -extern void -xmlrpc_client_event_loop_finish_asynch(void); - - -/* Finish all outstanding asynchronous calls. */ -extern void -xmlrpc_client_event_loop_finish_asynch_timeout(timeout_t const milliseconds); - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _XMLRPC_CLIENT_H_ */ diff --git a/Utilities/cmxmlrpc/xmlrpc_client_int.h b/Utilities/cmxmlrpc/xmlrpc_client_int.h deleted file mode 100644 index c94a1c7a2f..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_client_int.h +++ /dev/null @@ -1,102 +0,0 @@ -/*============================================================================ - xmlrpc_client_int.h -============================================================================== - This header file defines the interface between client modules inside - xmlrpc-c. - - Use this in addition to xmlrpc_client.h, which defines the external - interface. - - Copyright information is at the end of the file. -============================================================================*/ - - -#ifndef _XMLRPC_CLIENT_INT_H_ -#define _XMLRPC_CLIENT_INT_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _xmlrpc_server_info { - char *_server_url; - char *_http_basic_auth; -}; - -/* Create a new server info record, with a copy of the old server. */ -extern xmlrpc_server_info * -xmlrpc_server_info_copy(xmlrpc_env *env, xmlrpc_server_info *aserver); - - -/*========================================================================= -** Transport Implementation functions. -**========================================================================= -*/ -#include "xmlrpc_transport.h" - -/* The generalized event loop. This uses the above flags. For more details, -** see the wrapper functions below. If you're not using the timeout, the -** 'milliseconds' parameter will be ignored. -** Note that ANY event loop call will return immediately if there are -** no outstanding XML-RPC calls. */ -extern void -xmlrpc_client_event_loop_run_general (int flags, timeout_t milliseconds); - -/* Run the event loop forever. The loop will exit if someone calls -** xmlrpc_client_event_loop_end. */ -extern void -xmlrpc_client_event_loop_run (void); - -/* Run the event loop forever. The loop will exit if someone calls -** xmlrpc_client_event_loop_end or the timeout expires. -** (Note that ANY event loop call will return immediately if there are -** no outstanding XML-RPC calls.) */ -extern void -xmlrpc_client_event_loop_run_timeout (timeout_t milliseconds); - -/* End the running event loop immediately. This can also be accomplished -** by calling the corresponding function in libwww. -** (Note that ANY event loop call will return immediately if there are -** no outstanding XML-RPC calls.) */ -extern void -xmlrpc_client_event_loop_end (void); - - -/* Return true if there are uncompleted asynchronous calls. -** The exact value of this during a response callback is undefined. */ -extern int -xmlrpc_client_asynch_calls_are_unfinished (void); - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - - - diff --git a/Utilities/cmxmlrpc/xmlrpc_config.h.in b/Utilities/cmxmlrpc/xmlrpc_config.h.in deleted file mode 100644 index 9683c1e694..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_config.h.in +++ /dev/null @@ -1,88 +0,0 @@ -/* xmlrpc_config.h is generated from xmlrpc_config.h.in by 'configure'. - - This file just uses plain AC_SUBST substitution, the same as - Makefile.config. Wherever you see @XXX@, that gets replaced by the - value of 'configure' variable XXX. - - Logical macros are 0 or 1 instead of the more traditional defined and - undefined. That's so we can distinguish when compiling code between - "false" and some problem with the code. -*/ - - -/* We hope to replace xmlrpc_amconfig.h some day with something that - doesn't require a whole special set of software to build, to make - xmlrpc-c approachable by dumber developers. -*/ -#include "xmlrpc_amconfig.h" - -#ifndef __xmlrpc_config_h__ -#define __xmlrpc_config_h__ - - -#define VA_LIST_IS_ARRAY @VA_LIST_IS_ARRAY_DEFINE@ - -#cmakedefine HAS_VA_COPY @HAS_VA_COPY@ - -#define HAVE_LIBWWW_SSL @HAVE_LIBWWW_SSL_DEFINE@ - -#define ATTR_UNUSED @ATTR_UNUSED@ - -#cmakedefine HAVE_UNICODE_WCHAR @HAVE_UNICODE_WCHAR@ - -#define DIRECTORY_SEPARATOR "@DIRECTORY_SEPARATOR@" - -#cmakedefine HAVE_PTHREADS @HAVE_PTHREADS@ - -/* Xmlrpc-c code uses __inline__ to declare functions that should - be compiled as inline code. GNU C recognizes the __inline__ keyword. - Others recognize 'inline' or '__inline' or nothing at all to say - a function should be inlined. - - We could make 'configure' simply do a trial compile to figure out - which one, but for now, this approximation is easier: -*/ -#ifdef _WIN32 -# define __inline__ __inline -#else -# ifndef __GNUC__ -# ifndef __inline__ -# ifdef __sgi -# define __inline__ __inline -# else -# define __inline__ -# endif -# endif -# endif -#endif - -/* A timeout in milliseconds. */ -typedef unsigned long timeout_t; - -#if !defined(WIN32) && defined(_WIN32) -# define WIN32 -#endif -#if defined(WIN32) -#include -#include -#include - #if !defined (vsnprintf) -#define vsnprintf _vsnprintf - #endif - #if !defined (snprintf) -#define snprintf _snprintf - #endif -#include -#include -#include /* for _chdir() */ - - -/* -__inline BOOL setenv(const char* name, const char* value, int i) -{ - return (SetEnvironmentVariable(name, value) != 0) ? TRUE : FALSE; -} -*/ -#endif - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_curl_transport.c b/Utilities/cmxmlrpc/xmlrpc_curl_transport.c deleted file mode 100644 index 5726663bca..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_curl_transport.c +++ /dev/null @@ -1,759 +0,0 @@ -/*============================================================================= - xmlrpc_curl_transport -=============================================================================== - Curl-based client transport for Xmlrpc-c - - By Bryan Henderson 04.12.10. - - Contributed to the public domain by its author. -=============================================================================*/ - -#include "xmlrpc_config.h" - -#if defined(__BEOS__) -/* Some helpful system header has char==bool, then bool.h does int==bool. */ -#define HAVE_BOOL 1 -#endif - -#include "bool.h" -#include "mallocvar.h" -#include "linklist.h" -#include "casprintf.h" -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_client.h" -#include "xmlrpc_client_int.h" - -#include -#include -#include - -#if defined(HAVE_PTHREADS) -# include "xmlrpc_pthreads.h" -#endif - -#include -#include -#include - -#ifndef WIN32 -# include -#endif - -#if defined (WIN32) && defined(_DEBUG) -# include -# define new DEBUG_NEW -# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) -# undef THIS_FILE - static char THIS_FILE[] = __FILE__; -#endif /*WIN32 && _DEBUG*/ - -static void xmlrpc_abort(void) -{ - abort(); -} - -struct clientTransport { -#if defined (HAVE_PTHREADS) - pthread_mutex_t listLock; -#endif - struct list_head rpcList; - /* List of all RPCs that exist for this transport. An RPC exists - from the time the user requests it until the time the user - acknowledges it is done. - */ -}; - -typedef struct { - /* This is all stuff that really ought to be in the CURL object, - but the Curl library is a little too simple for that. So we - build a layer on top of it, and call it a "transaction," as - distinct from the Curl "session" represented by the CURL object. - */ - CURL * curlSessionP; - /* Handle for Curl library session object */ - char curlError[CURL_ERROR_SIZE]; - /* Error message from Curl */ - struct curl_slist * headerList; - /* The HTTP headers for the transaction */ - const char * serverUrl; /* malloc'ed - belongs to this object */ -} curlTransaction; - - - -typedef struct { - struct list_head link; /* link in transport's list of RPCs */ - curlTransaction * curlTransactionP; - /* The object which does the HTTP transaction, with no knowledge - of XML-RPC or Xmlrpc-c. - */ - xmlrpc_mem_block * responseXmlP; - xmlrpc_bool threadExists; -#if defined(HAVE_PTHREADS) - pthread_t thread; -#endif - transport_asynch_complete complete; - /* Routine to call to complete the RPC after it is complete HTTP-wise. - NULL if none. - */ - struct call_info * callInfoP; - /* User's identifier for this RPC */ -} rpc; - - - -static size_t -collect(void * const ptr, - size_t const size, - size_t const nmemb, - FILE * const stream) { -/*---------------------------------------------------------------------------- - This is a Curl output function. Curl calls this to deliver the - HTTP response body. Curl thinks it's writing to a POSIX stream. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * const responseXmlP = (xmlrpc_mem_block *) stream; - char * const buffer = ptr; - size_t const length = nmemb * size; - - size_t retval; - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_mem_block_append(&env, responseXmlP, buffer, length); - if (env.fault_occurred) - retval = (size_t)-1; - else - /* Really? Shouldn't it be like fread() and return 'nmemb'? */ - retval = length; - - return retval; -} - - - -static void -initWindowsStuff(xmlrpc_env * const envP) { - -#if defined (WIN32) - /* This is CRITICAL so that cURL-Win32 works properly! */ - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD(1, 1); - - err = WSAStartup(wVersionRequested, &wsaData); - (void)err; - if (LOBYTE(wsaData.wVersion) != 1 || - HIBYTE( wsaData.wVersion) != 1) { - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - WSACleanup(); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Winsock reported that " - "it does not implement the requested version 1.1."); - } -#else - if (0) - envP->fault_occurred = TRUE; /* Avoid unused parm warning */ -#endif -} - - -static void -create(xmlrpc_env * const envP, - int const flags ATTR_UNUSED, - const char * const appname ATTR_UNUSED, - const char * const appversion ATTR_UNUSED, - struct clientTransport ** const handlePP) { -/*---------------------------------------------------------------------------- - This does the 'create' operation for a Curl client transport. ------------------------------------------------------------------------------*/ - struct clientTransport * transportP; - - initWindowsStuff(envP); - - MALLOCVAR(transportP); - if (transportP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unable to allocate transport descriptor."); - else { -#ifdef HAVE_PTHREADS - pthread_mutex_init(&transportP->listLock, NULL); -#endif - - list_make_empty(&transportP->rpcList); - - /* - * This is the main global constructor for the app. Call this before - * _any_ libcurl usage. If this fails, *NO* libcurl functions may be - * used, or havoc may be the result. - */ - curl_global_init(CURL_GLOBAL_ALL); - - /* The above makes it look like Curl is not re-entrant. We should - check into that. - */ - - *handlePP = transportP; - } -} - - -static void -termWindowStuff(void) { - -#if defined (WIN32) - WSACleanup(); -#endif -} - - - -static void -destroy(struct clientTransport * const clientTransportP) { -/*---------------------------------------------------------------------------- - This does the 'destroy' operation for a Libwww client transport. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT(clientTransportP != NULL); - - XMLRPC_ASSERT(list_is_empty(&clientTransportP->rpcList)); - -#if defined(HAVE_PTHREADS) - pthread_mutex_destroy(&clientTransportP->listLock); -#endif - - curl_global_cleanup(); - - termWindowStuff(); - - free(clientTransportP); -} - - - -static void -createCurlHeaderList(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - struct curl_slist ** const headerListP) { - - struct curl_slist * headerList; - - headerList = NULL; /* initial value */ - - headerList = curl_slist_append(headerList, "Content-Type: text/xml"); - - if (headerList == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Could not add header. curl_slist_append() failed."); - else { - /* Send an authorization header if we need one. */ - if (serverP->_http_basic_auth) { - /* Make the authentication header "Authorization: " */ - /* we need 15 + length of _http_basic_auth + 1 for null */ - - char * const authHeader = - malloc(strlen(serverP->_http_basic_auth) + 15 + 1); - - if (authHeader == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for authentication header"); - else { - memcpy(authHeader,"Authorization: ", 15); - memcpy(authHeader + 15, serverP->_http_basic_auth, - strlen(serverP->_http_basic_auth) + 1); - - headerList = curl_slist_append(headerList, authHeader); - if (headerList == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Could not add authentication header. " - "curl_slist_append() failed."); - free(authHeader); - } - } - if (envP->fault_occurred) - free(headerList); - } - *headerListP = headerList; -} - - - -static void -setupCurlSession(xmlrpc_env * const envP, - CURL * const curlSessionP, - curlTransaction * const curlTransactionP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP) { - - static char proxy[1024]; - static char proxyUser[1024]; - int proxy_type = 0; - - if ( getenv("HTTP_PROXY") ) - { - proxy_type = 1; - if (getenv("HTTP_PROXY_PORT") ) - { - sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT")); - } - else - { - sprintf(proxy, "%s", getenv("HTTP_PROXY")); - } - if ( getenv("HTTP_PROXY_TYPE") ) - { - /* HTTP/SOCKS4/SOCKS5 */ - if ( strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0 ) - { - proxy_type = 1; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0 ) - { - proxy_type = 2; - } - else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0 ) - { - proxy_type = 3; - } - } - if ( getenv("HTTP_PROXY_USER") ) - { - strcpy(proxyUser, getenv("HTTP_PROXY_USER")); - } - if ( getenv("HTTP_PROXY_PASSWD") ) - { - strcat(proxyUser, ":"); - strcat(proxyUser, getenv("HTTP_PROXY_PASSWD")); - } - } - /* Using proxy */ - if ( proxy_type > 0 ) - { - curl_easy_setopt(curlSessionP, CURLOPT_PROXY, proxy); - switch (proxy_type) - { - case 2: - curl_easy_setopt(curlSessionP, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); - break; - case 3: - curl_easy_setopt(curlSessionP, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - break; - default: - curl_easy_setopt(curlSessionP, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); - if (*proxyUser) - { - curl_easy_setopt(curlSessionP, CURLOPT_PROXYUSERPWD, proxyUser); - } - } - } - - curl_easy_setopt(curlSessionP, CURLOPT_POST, 1 ); - curl_easy_setopt(curlSessionP, CURLOPT_URL, curlTransactionP->serverUrl); - XMLRPC_MEMBLOCK_APPEND(char, envP, callXmlP, "\0", 1); - if (!envP->fault_occurred) { - curl_easy_setopt(curlSessionP, CURLOPT_POSTFIELDS, - XMLRPC_MEMBLOCK_CONTENTS(char, callXmlP)); - - curl_easy_setopt(curlSessionP, CURLOPT_FILE, responseXmlP); - curl_easy_setopt(curlSessionP, CURLOPT_HEADER, 0 ); - curl_easy_setopt(curlSessionP, CURLOPT_WRITEFUNCTION, collect); - curl_easy_setopt(curlSessionP, CURLOPT_ERRORBUFFER, - curlTransactionP->curlError); - curl_easy_setopt(curlSessionP, CURLOPT_NOPROGRESS, 1); - - curl_easy_setopt(curlSessionP, CURLOPT_HTTPHEADER, - curlTransactionP->headerList); - } -} - - - -static void -createCurlTransaction(xmlrpc_env * const envP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - curlTransaction ** const curlTransactionPP) { - - curlTransaction * curlTransactionP; - - MALLOCVAR(curlTransactionP); - if (curlTransactionP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "No memory to create Curl transaction."); - else { - CURL * const curlSessionP = curl_easy_init(); - - if (curlSessionP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Could not create Curl session. curl_easy_init() failed."); - else { - curlTransactionP->curlSessionP = curlSessionP; - - curlTransactionP->serverUrl = strdup(serverP->_server_url); - if (curlTransactionP->serverUrl == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Out of memory to store server URL."); - else { - createCurlHeaderList(envP, serverP, - &curlTransactionP->headerList); - - if (!envP->fault_occurred) - setupCurlSession(envP, curlSessionP, curlTransactionP, - callXmlP, responseXmlP); - - if (envP->fault_occurred) - strfree(curlTransactionP->serverUrl); - } - if (envP->fault_occurred) - curl_easy_cleanup(curlSessionP); - } - if (envP->fault_occurred) - free(curlTransactionP); - } - *curlTransactionPP = curlTransactionP; -} - - - -static void -destroyCurlTransaction(curlTransaction * const curlTransactionP) { - - curl_slist_free_all(curlTransactionP->headerList); - strfree(curlTransactionP->serverUrl); - curl_easy_cleanup(curlTransactionP->curlSessionP); - free(curlTransactionP); -} - - -static void -performCurlTransaction(xmlrpc_env * const envP, - curlTransaction * const curlTransactionP) { - - CURL * const curlSessionP = curlTransactionP->curlSessionP; - - CURLcode res; - - res = curl_easy_perform(curlSessionP); - - if (res != CURLE_OK) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, "Curl failed to perform " - "HTTP POST request. curl_easy_perform() says: %s (%d)", - curlTransactionP->curlError, res); - else { - CURLcode crRes; - long http_result; - crRes = curl_easy_getinfo(curlSessionP, CURLINFO_HTTP_CODE, - &http_result); - - if (crRes != CURLE_OK) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Curl performed the HTTP POST request, but was " - "unable to say what the HTTP result code was. " - "curl_easy_getinfo(CURLINFO_HTTP_CODE) says: %s", - curlTransactionP->curlError); - else { - if (http_result != 200) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NETWORK_ERROR, "HTTP response: %ld", - http_result); - } - } -} - - -#if defined(HAVE_PTHREADS) - -static void -doAsyncRpc2(void * const arg) { - - rpc * const rpcP = arg; - - xmlrpc_env env; - - xmlrpc_env_init(&env); - - performCurlTransaction(&env, rpcP->curlTransactionP); - - rpcP->complete(rpcP->callInfoP, rpcP->responseXmlP, env); - - xmlrpc_env_clean(&env); -} - - - -#ifdef WIN32 - -static unsigned __stdcall -doAsyncRpc(void * arg) { - doAsyncRpc2(arg); - return 0; -} - -#else - -static void * -doAsyncRpc(void * arg) { - doAsyncRpc2(arg); - return NULL; -} - -#endif - - -static void -createRpcThread(xmlrpc_env * const envP, - rpc * const rpcP, - pthread_t * const threadP) { - - int rc; - - rc = pthread_create(threadP, NULL, doAsyncRpc, rpcP); - switch (rc) { - case 0: - break; - case EAGAIN: - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "pthread_create() failed: System Resources exceeded."); - break; - case EINVAL: - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "pthread_create() failed: Param Error for attr."); - break; - case ENOMEM: - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "pthread_create() failed: No memory for new thread."); - break; - default: - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "pthread_create() failed: Unrecognized error code %d.", rc); - break; - } -} -#endif - - - -static void -rpcCreate(xmlrpc_env * const envP, - struct clientTransport * const clientTransportP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - xmlrpc_mem_block * const responseXmlP, - transport_asynch_complete complete, - struct call_info * const callInfoP, - rpc ** const rpcPP) { - - rpc * rpcP; - - MALLOCVAR(rpcP); - if (rpcP == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for rpc object"); - else { - rpcP->callInfoP = callInfoP; - rpcP->complete = complete; - rpcP->responseXmlP = responseXmlP; - rpcP->threadExists = FALSE; - - createCurlTransaction(envP, serverP, - callXmlP, responseXmlP, - &rpcP->curlTransactionP); - if (!envP->fault_occurred) { - if (complete) { -#if defined(HAVE_PTHREADS) - createRpcThread(envP, rpcP, &rpcP->thread); -#else - xmlrpc_abort(); -#endif - if (!envP->fault_occurred) - rpcP->threadExists = TRUE; - } - if (!envP->fault_occurred) { - list_init_header(&rpcP->link, rpcP); -#if defined(HAVE_PTHREADS) - pthread_mutex_lock(&clientTransportP->listLock); -#endif - list_add_head(&clientTransportP->rpcList, &rpcP->link); -#if defined(HAVE_PTHREADS) - pthread_mutex_unlock(&clientTransportP->listLock); -#endif - } - if (envP->fault_occurred) - destroyCurlTransaction(rpcP->curlTransactionP); - } - if (envP->fault_occurred) - { - free(rpcP); - rpcP = 0; /* set this to null as it is used later on */ - } - } - *rpcPP = rpcP; -} - - -static void -rpcDestroy(rpc * const rpcP) { - - XMLRPC_ASSERT_PTR_OK(rpcP); - XMLRPC_ASSERT(!rpcP->threadExists); - - destroyCurlTransaction(rpcP->curlTransactionP); - - list_remove(&rpcP->link); - - free(rpcP); -} - - -static void -sendRequest(xmlrpc_env * const envP, - struct clientTransport * const clientTransportP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - transport_asynch_complete complete, - struct call_info * const callInfoP) { -/*---------------------------------------------------------------------------- - Initiate an XML-RPC rpc asynchronously. Don't wait for it to go to - the server. - - Unless we return failure, we arrange to have complete() called when - the rpc completes. - - This does the 'send_request' operation for a Curl client transport. ------------------------------------------------------------------------------*/ - rpc * rpcP; - xmlrpc_mem_block * responseXmlP; - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, - complete, callInfoP, - &rpcP); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } - /* The user's eventual finish_asynch call will destroy this RPC - and response buffer - */ -} - - - -static void * -finishRpc(struct list_head * const headerP, - void * const context ATTR_UNUSED) { - - rpc * const rpcP = headerP->itemP; - - if (rpcP->threadExists) { -#if defined(HAVE_PTHREADS) - void *status; - int result; - - result = pthread_join(rpcP->thread, &status); - (void)result; -#else - xmlrpc_abort(); -#endif - - rpcP->threadExists = FALSE; - } - - XMLRPC_MEMBLOCK_FREE(char, rpcP->responseXmlP); - - rpcDestroy(rpcP); - - return NULL; -} - - - -static void -finishAsynch(struct clientTransport * const clientTransportP ATTR_UNUSED, - enum timeoutType const timeoutType ATTR_UNUSED, - timeout_t const timeout ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - Wait for the threads of all outstanding RPCs to exit and destroy those - RPCs. - - This does the 'finish_asynch' operation for a Curl client transport. ------------------------------------------------------------------------------*/ - /* We ignore any timeout request. Some day, we should figure out how - to set an alarm and interrupt running threads. - */ - -#if defined(HAVE_PTHREADS) - pthread_mutex_lock(&clientTransportP->listLock); -#else - xmlrpc_abort(); -#endif - - list_foreach(&clientTransportP->rpcList, finishRpc, NULL); - -#if defined(HAVE_PTHREADS) - pthread_mutex_unlock(&clientTransportP->listLock); -#else - xmlrpc_abort(); -#endif -} - - - -static void -call(xmlrpc_env * const envP, - struct clientTransport * const clientTransportP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const callXmlP, - struct call_info * const callInfoP, - xmlrpc_mem_block ** const responsePP) { - - xmlrpc_mem_block * responseXmlP; - rpc * rpcP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(serverP); - XMLRPC_ASSERT_PTR_OK(callXmlP); - XMLRPC_ASSERT_PTR_OK(callInfoP); - XMLRPC_ASSERT_PTR_OK(responsePP); - - responseXmlP = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - rpcCreate(envP, clientTransportP, serverP, callXmlP, responseXmlP, - NULL, NULL, &rpcP); - if (!envP->fault_occurred) { - performCurlTransaction(envP, rpcP->curlTransactionP); - - *responsePP = responseXmlP; - - rpcDestroy(rpcP); - } - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, responseXmlP); - } -} - - - -struct clientTransportOps xmlrpc_curl_transport_ops = { - &create, - &destroy, - &sendRequest, - &call, - &finishAsynch, -}; diff --git a/Utilities/cmxmlrpc/xmlrpc_curl_transport.h b/Utilities/cmxmlrpc/xmlrpc_curl_transport.h deleted file mode 100644 index 8fc6f682ab..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_curl_transport.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef XMLRPC_CURL_TRANSPORT_H -#define XMLRPC_CURL_TRANSPORT_H - -#include "xmlrpc_transport.h" - -extern struct clientTransportOps xmlrpc_curl_transport_ops; - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_data.c b/Utilities/cmxmlrpc/xmlrpc_data.c deleted file mode 100644 index 456d8e4879..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_data.c +++ /dev/null @@ -1,1334 +0,0 @@ -/* Copyright information is at end of file */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "bool.h" -#include "xmlrpc.h" -#include "xmlrpc_int.h" - -/* Borrowed from Python 1.5.2. -** MPW pushes 'extended' for float and double types with varargs */ -#ifdef MPW -typedef extended va_double; -#else -typedef double va_double; -#endif - -/* Borrowed from Python 1.5.2. -** Python copies its va_list objects before using them in certain -** tricky fashions. We don't why Python does this, but since we're -** abusing our va_list objects in a similar fashion, we'll copy them -** too. */ -#ifdef HAS_VA_COPY -# define VA_LIST_COPY(dest,src) va_copy((dest), (src)) -#else -# if VA_LIST_IS_ARRAY -# define VA_LIST_COPY(dest,src) memcpy((dest), (src), sizeof(va_list)) -# else -# define VA_LIST_COPY(dest,src) ((dest) = (src)) -# endif -#endif - - -static void -destroyValue(xmlrpc_value * const valueP) { - - /* First, we need to destroy this value's contents, if any. */ - switch (valueP->_type) { - case XMLRPC_TYPE_INT: - case XMLRPC_TYPE_BOOL: - case XMLRPC_TYPE_DOUBLE: - break; - - case XMLRPC_TYPE_ARRAY: - xmlrpc_destroyArrayContents(valueP); - break; - - case XMLRPC_TYPE_STRING: -#ifdef HAVE_UNICODE_WCHAR - if (valueP->_wcs_block) - xmlrpc_mem_block_free(valueP->_wcs_block); -#endif /* HAVE_UNICODE_WCHAR */ - /* Fall through. */ - - case XMLRPC_TYPE_DATETIME: - case XMLRPC_TYPE_BASE64: - xmlrpc_mem_block_clean(&valueP->_block); - break; - - case XMLRPC_TYPE_STRUCT: - xmlrpc_destroyStruct(valueP); - break; - - case XMLRPC_TYPE_C_PTR: - break; - - case XMLRPC_TYPE_DEAD: - XMLRPC_ASSERT(FALSE); /* Can't happen, per entry conditions */ - - default: - XMLRPC_ASSERT(FALSE); /* There are no other possible values */ - } - - /* Next, we mark this value as invalid, to help catch refcount - ** errors. */ - valueP->_type = XMLRPC_TYPE_DEAD; - - /* Finally, we destroy the value itself. */ - free(valueP); -} - - - -/*========================================================================= -** Reference Counting -**========================================================================= -** Some simple reference-counting code. The xmlrpc_DECREF routine is in -** charge of destroying values when their reference count equals zero. -*/ - -void -xmlrpc_INCREF (xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_VALUE_OK(valueP); - XMLRPC_ASSERT(valueP->_refcount > 0); - - valueP->_refcount++; -} - - - -void -xmlrpc_DECREF (xmlrpc_value * const valueP) { - - XMLRPC_ASSERT_VALUE_OK(valueP); - XMLRPC_ASSERT(valueP->_refcount > 0); - XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD); - - valueP->_refcount--; - - /* If we have no more refs, we need to deallocate this value. */ - if (valueP->_refcount == 0) - destroyValue(valueP); -} - - - -/*========================================================================= - Utiltiies -=========================================================================*/ - -static const char * -typeName(xmlrpc_type const type) { - - switch(type) { - - case XMLRPC_TYPE_INT: return "INT"; - case XMLRPC_TYPE_BOOL: return "BOOL"; - case XMLRPC_TYPE_DOUBLE: return "DOUBLE"; - case XMLRPC_TYPE_DATETIME: return "DATETIME"; - case XMLRPC_TYPE_STRING: return "STRING"; - case XMLRPC_TYPE_BASE64: return "BASE64"; - case XMLRPC_TYPE_ARRAY: return "ARRAY"; - case XMLRPC_TYPE_STRUCT: return "STRUCT"; - case XMLRPC_TYPE_C_PTR: return "C_PTR"; - case XMLRPC_TYPE_DEAD: return "DEAD"; - default: return "???"; - } -} - - - -static void -verifyNoNulls(xmlrpc_env * const envP, - const char * const contents, - unsigned int const len) { -/*---------------------------------------------------------------------------- - Verify that the character array 'contents', which is 'len' bytes long, - does not contain any NUL characters, which means it can be made into - a passable ASCIIZ string just by adding a terminating NUL. - - Fail if the array contains a NUL. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < len && !envP->fault_occurred; i++) - if (contents[i] == '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "String must not contain NUL characters"); -} - - - -static void -verifyNoNullsW(xmlrpc_env * const envP, - const wchar_t * const contents, - unsigned int const len) { -/*---------------------------------------------------------------------------- - Same as verifyNoNulls(), but for wide characters. ------------------------------------------------------------------------------*/ - unsigned int i; - - for (i = 0; i < len && !envP->fault_occurred; i++) - if (contents[i] == '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, - "String must not contain NUL characters"); -} - - - -static void -validateType(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_type const expectedType) { - - if (valueP->_type != expectedType) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where " - "type %s was expected.", - typeName(valueP->_type), typeName(expectedType)); - } -} - - - -/*========================================================================= - Extracting XML-RPC value -=========================================================================== - These routines extract XML-RPC values into ordinary C data types. - - For array and struct values, see the separates files xmlrpc_array.c - and xmlrpc_struct.c. -=========================================================================*/ - -void -xmlrpc_read_int(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_int32 * const intValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_INT); - if (!envP->fault_occurred) - *intValueP = valueP->_value.i; -} - - - -void -xmlrpc_read_double(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_double * const doubleValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_DOUBLE); - if (!envP->fault_occurred) - *doubleValueP = valueP->_value.d; - -} - - - -void -xmlrpc_read_bool(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - xmlrpc_bool * const boolValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_BOOL); - if (!envP->fault_occurred) - *boolValueP = valueP->_value.b; -} - - - -void -xmlrpc_read_string(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - const char ** const stringValueP) { -/*---------------------------------------------------------------------------- - Read the value of an XML-RPC string an ASCIIZ string. - - Fail if the string contains null characters (which means it wasn't - really a string, but XML-RPC doesn't seem to understand what a string - is, and such values are possible). ------------------------------------------------------------------------------*/ - validateType(envP, valueP, XMLRPC_TYPE_STRING); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - - verifyNoNulls(envP, contents, (unsigned int)size); - if (!envP->fault_occurred) { - char * stringValue; - - stringValue = malloc(size+1); - if (stringValue == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate space " - "for %u-character string", size); - else { - memcpy(stringValue, - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block), size); - stringValue[size] = '\0'; - - *stringValueP = stringValue; - } - } - } -} - - - -void -xmlrpc_read_string_lp(xmlrpc_env * const envP, - const xmlrpc_value * const valueP, - unsigned int * const lengthP, - const char ** const stringValueP) { - - validateType(envP, valueP, XMLRPC_TYPE_STRING); - if (!envP->fault_occurred) { - size_t const size = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - const char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - - char * stringValue; - - stringValue = malloc(size); - if (stringValue == NULL) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate %u bytes " - "for string.", size); - else { - memcpy(stringValue, contents, size); - *stringValueP = stringValue; - *lengthP = (unsigned int)size; - } - } -} - - - -/*========================================================================= -** Building XML-RPC values. -**========================================================================= -** Build new XML-RPC values from a format string. This code is heavily -** inspired by Py_BuildValue from Python 1.5.2. In particular, our -** particular abuse of the va_list data type is copied from the equivalent -** Python code in modsupport.c. Since Python is portable, our code should -** (in theory) also be portable. -*/ - - -xmlrpc_type xmlrpc_value_type (xmlrpc_value* value) -{ - XMLRPC_ASSERT_VALUE_OK(value); - return value->_type; -} - - - -static void -createXmlrpcValue(xmlrpc_env * const envP, - xmlrpc_value ** const valPP) { -/*---------------------------------------------------------------------------- - Create a blank xmlrpc_value to be filled in. - - Set the reference count to 1. ------------------------------------------------------------------------------*/ - xmlrpc_value * valP; - - valP = (xmlrpc_value*) malloc(sizeof(xmlrpc_value)); - if (!valP) - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for xmlrpc_value"); - else - valP->_refcount = 1; - - *valPP = valP; -} - - - -static void -mkInt(xmlrpc_env * const envP, - xmlrpc_int32 const value, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_INT; - valP->_value.i = value; - } - *valPP = valP; -} - - - -static void -mkBool(xmlrpc_env * const envP, - xmlrpc_bool const value, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_BOOL; - valP->_value.b = value; - } - *valPP = valP; -} - - - -static void -mkDouble(xmlrpc_env * const envP, - double const value, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_DOUBLE; - valP->_value.d = value; - } - *valPP = valP; -} - - - -#ifdef HAVE_UNICODE_WCHAR -#define MAKE_WCS_BLOCK_NULL(val) ((val)->_wcs_block = NULL) -#else -#define MAKE_WCS_BLOCK_NULL(val) do {} while(0) -#endif - - - -static void -mkString(xmlrpc_env * const envP, - const char * const value, - unsigned int const length, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_STRING; - MAKE_WCS_BLOCK_NULL(valP); - XMLRPC_MEMBLOCK_INIT(char, envP, &valP->_block, length + 1); - if (!envP->fault_occurred) { - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valP->_block); - memcpy(contents, value, length); - contents[length] = '\0'; - } - if (envP->fault_occurred) - free(valP); - } - *valPP = valP; -} - - - -static void -getString(xmlrpc_env * const envP, - const char ** const formatP, - va_list * const args, - xmlrpc_value ** const valPP) { - - const char * str; - size_t len; - - str = (const char*) va_arg(*args, char*); - if (**formatP == '#') { - (*formatP)++; - len = (size_t) va_arg(*args, size_t); - } else - len = strlen(str); - - mkString(envP, str, (unsigned int)len, valPP); -} - - - -#ifdef HAVE_UNICODE_WCHAR -static void -mkWideString(xmlrpc_env * const envP, - wchar_t * const wcs, - size_t const wcs_len, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - char *contents; - wchar_t *wcs_contents; - int block_is_inited; - xmlrpc_mem_block *utf8_block; - char *utf8_contents; - size_t utf8_len; - - /* Error-handling preconditions. */ - utf8_block = NULL; - block_is_inited = 0; - - /* Initialize our XML-RPC value. */ - valP = (xmlrpc_value*) malloc(sizeof(xmlrpc_value)); - XMLRPC_FAIL_IF_NULL(valP, envP, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for wide string"); - valP->_refcount = 1; - valP->_type = XMLRPC_TYPE_STRING; - - /* More error-handling preconditions. */ - valP->_wcs_block = NULL; - - /* Build our wchar_t block first. */ - valP->_wcs_block = - XMLRPC_TYPED_MEM_BLOCK_NEW(wchar_t, envP, wcs_len + 1); - XMLRPC_FAIL_IF_FAULT(envP); - wcs_contents = - XMLRPC_TYPED_MEM_BLOCK_CONTENTS(wchar_t, valP->_wcs_block); - memcpy(wcs_contents, wcs, wcs_len * sizeof(wchar_t)); - wcs_contents[wcs_len] = '\0'; - - /* Convert the wcs block to UTF-8. */ - utf8_block = xmlrpc_wcs_to_utf8(envP, wcs_contents, wcs_len + 1); - XMLRPC_FAIL_IF_FAULT(envP); - utf8_contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, utf8_block); - utf8_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, utf8_block); - - /* XXX - We need an extra memcopy to initialize _block. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &valP->_block, utf8_len); - XMLRPC_FAIL_IF_FAULT(envP); - block_is_inited = 1; - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &valP->_block); - memcpy(contents, utf8_contents, utf8_len); - - cleanup: - if (utf8_block) - xmlrpc_mem_block_free(utf8_block); - if (envP->fault_occurred) { - if (valP) { - if (valP->_wcs_block) - xmlrpc_mem_block_free(valP->_wcs_block); - if (block_is_inited) - xmlrpc_mem_block_clean(&valP->_block); - free(valP); - } - } - *valPP = valP; -} -#endif /* HAVE_UNICODE_WCHAR */ - - - -static void -getWideString(xmlrpc_env * const envP, - const char ** const formatP, - va_list * const args, - xmlrpc_value ** const valPP) { -#ifdef HAVE_UNICODE_WCHAR - - wchar_t *wcs; - size_t len; - - wcs = (wchar_t*) va_arg(*args, wchar_t*); - if (**formatP == '#') { - (*formatP)++; - len = (size_t) va_arg(*args, size_t); - } else - len = wcslen(wcs); - - mkWideString(envP, wcs, len, valPP); - -#endif /* HAVE_UNICODE_WCHAR */ -} - - - -static void -mkDatetime(xmlrpc_env * const envP, - const char * const value, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_DATETIME; - - XMLRPC_TYPED_MEM_BLOCK_INIT( - char, envP, &valP->_block, strlen(value) + 1); - if (!envP->fault_occurred) { - char * const contents = - XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &valP->_block); - strcpy(contents, value); - } - if (envP->fault_occurred) - free(valP); - } - *valPP = valP; -} - - - -static void -mkBase64(xmlrpc_env * const envP, - const unsigned char * const value, - size_t const length, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_BASE64; - - xmlrpc_mem_block_init(envP, &valP->_block, length); - if (!envP->fault_occurred) { - char * const contents = - xmlrpc_mem_block_contents(&valP->_block); - memcpy(contents, value, length); - } - if (envP->fault_occurred) - free(valP); - } - *valPP = valP; -} - - - -static void -getBase64(xmlrpc_env * const envP, - va_list * const args, - xmlrpc_value ** const valPP) { - - unsigned char * value; - size_t length; - - value = (unsigned char*) va_arg(*args, unsigned char*); - length = (size_t) va_arg(*args, size_t); - - mkBase64(envP, value, length, valPP); -} - - - -static void -mkCPtr(xmlrpc_env * const envP, - void * const value, - xmlrpc_value ** const valPP) { - - xmlrpc_value * valP; - - createXmlrpcValue(envP, &valP); - - if (!envP->fault_occurred) { - valP->_type = XMLRPC_TYPE_C_PTR; - valP->_value.c_ptr = value; - } - *valPP = valP; -} - - - -static void -mkArrayFromVal(xmlrpc_env * const envP, - xmlrpc_value * const value, - xmlrpc_value ** const valPP) { - - if (xmlrpc_value_type(value) != XMLRPC_TYPE_ARRAY) - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Array format ('A'), non-array xmlrpc_value"); - else - xmlrpc_INCREF(value); - - *valPP = value; -} - - - -static void -mkStructFromVal(xmlrpc_env * const envP, - xmlrpc_value * const value, - xmlrpc_value ** const valPP) { - - if (xmlrpc_value_type(value) != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, - "Struct format ('S'), non-struct xmlrpc_value"); - else - xmlrpc_INCREF(value); - - *valPP = value; -} - - - -static void -getValue(xmlrpc_env * const envP, - const char** const format, - va_list * const args, - xmlrpc_value ** const valPP); - - - -static void -createXmlrpcArray(xmlrpc_env * const envP, - xmlrpc_value ** const arrayPP) { -/*---------------------------------------------------------------------------- - Create an empty array xmlrpc_value. ------------------------------------------------------------------------------*/ - xmlrpc_value * arrayP; - - createXmlrpcValue(envP, &arrayP); - if (!envP->fault_occurred) { - arrayP->_type = XMLRPC_TYPE_ARRAY; - XMLRPC_TYPED_MEM_BLOCK_INIT(xmlrpc_value*, envP, &arrayP->_block, 0); - if (envP->fault_occurred) - free(arrayP); - } - *arrayPP = arrayP; -} - - - -static void -getArray(xmlrpc_env * const envP, - const char ** const formatP, - char const delimiter, - va_list * const args, - xmlrpc_value ** const arrayPP) { - - xmlrpc_value * arrayP; - - createXmlrpcArray(envP, &arrayP); - - /* Add items to the array until we hit our delimiter. */ - - while (**formatP != delimiter && !envP->fault_occurred) { - - xmlrpc_value * itemP; - - if (**formatP == '\0') - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string ended before closing ')'."); - else { - getValue(envP, formatP, args, &itemP); - if (!envP->fault_occurred) { - xmlrpc_array_append_item(envP, arrayP, itemP); - xmlrpc_DECREF(itemP); - } - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(arrayP); - - *arrayPP = arrayP; -} - - - -static void -getStructMember(xmlrpc_env * const envP, - const char ** const formatP, - va_list * const args, - xmlrpc_value ** const keyPP, - xmlrpc_value ** const valuePP) { - - - /* Get the key */ - getValue(envP, formatP, args, keyPP); - if (!envP->fault_occurred) { - if (**formatP != ':') - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string does not have ':' after a " - "structure member key."); - else { - /* Skip over colon that separates key from value */ - (*formatP)++; - - /* Get the value */ - getValue(envP, formatP, args, valuePP); - } - if (envP->fault_occurred) - xmlrpc_DECREF(*keyPP); - } -} - - - -static void -getStruct(xmlrpc_env * const envP, - const char ** const formatP, - char const delimiter, - va_list * const args, - xmlrpc_value ** const structPP) { - - xmlrpc_value * structP; - - structP = xmlrpc_struct_new(envP); - if (!envP->fault_occurred) { - while (**formatP != delimiter && !envP->fault_occurred) { - xmlrpc_value * keyP; - xmlrpc_value * valueP; - - getStructMember(envP, formatP, args, &keyP, &valueP); - - if (!envP->fault_occurred) { - if (**formatP == ',') - (*formatP)++; /* Skip over the comma */ - else if (**formatP == delimiter) { - /* End of the line */ - } else - xmlrpc_env_set_fault( - envP, XMLRPC_INTERNAL_ERROR, - "format string does not have ',' or ')' after " - "a structure member"); - - if (!envP->fault_occurred) - /* Add the new member to the struct. */ - xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); - - xmlrpc_DECREF(valueP); - xmlrpc_DECREF(keyP); - } - } - if (envP->fault_occurred) - xmlrpc_DECREF(structP); - } - *structPP = structP; -} - - - -static void -getValue(xmlrpc_env * const envP, - const char** const formatP, - va_list * const args, - xmlrpc_value ** const valPP) { -/*---------------------------------------------------------------------------- - Get the next value from the list. *formatP points to the specifier - for the next value in the format string (i.e. to the type code - character) and we move *formatP past the whole specifier for the - next value. We read the required arguments from 'args'. We return - the value as *valPP with a reference to it. - - For example, if *formatP points to the "i" in the string "sis", - we read one argument from 'args' and return as *valP an integer whose - value is the argument we read. We advance *formatP to point to the - last 's' and advance 'args' to point to the argument that belongs to - that 's'. ------------------------------------------------------------------------------*/ - char const formatChar = *(*formatP)++; - - switch (formatChar) { - case 'i': - mkInt(envP, (xmlrpc_int32) va_arg(*args, xmlrpc_int32), valPP); - break; - - case 'b': - mkBool(envP, (xmlrpc_bool) va_arg(*args, xmlrpc_bool), valPP); - break; - - case 'd': - mkDouble(envP, (double) va_arg(*args, va_double), valPP); - break; - - case 's': - getString(envP, formatP, args, valPP); - break; - - case 'w': - getWideString(envP, formatP, args, valPP); - break; - - /* The code 't' is reserved for a better, time_t based - implementation of dateTime conversion. - */ - case '8': - mkDatetime(envP, (char*) va_arg(*args, char*), valPP); - break; - - case '6': - getBase64(envP, args, valPP); - break; - - case 'p': - /* We might someday want to use the code 'p!' to read in a - cleanup function for this pointer. - */ - mkCPtr(envP, (void*) va_arg(*args, void*), valPP); - break; - - case 'A': - mkArrayFromVal(envP, (xmlrpc_value*) va_arg(*args, xmlrpc_value*), - valPP); - break; - - case 'S': - mkStructFromVal(envP, (xmlrpc_value*) va_arg(*args, xmlrpc_value*), - valPP); - break; - - case 'V': - *valPP = (xmlrpc_value*) va_arg(*args, xmlrpc_value*); - xmlrpc_INCREF(*valPP); - break; - - case '(': - getArray(envP, formatP, ')', args, valPP); - if (!envP->fault_occurred) { - XMLRPC_ASSERT(**formatP == ')'); - (*formatP)++; /* Skip over closing parenthesis */ - } - break; - - case '{': - getStruct(envP, formatP, '}', args, valPP); - if (!envP->fault_occurred) { - XMLRPC_ASSERT(**formatP == '}'); - (*formatP)++; /* Skip over closing brace */ - } - break; - - default: { - const char * const badCharacter = xmlrpc_makePrintableChar(formatChar); - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "Unexpected character '%s' in format string", badCharacter); - xmlrpc_strfree(badCharacter); - } - } -} - - - -void -xmlrpc_build_value_va(xmlrpc_env * const envP, - const char * const format, - va_list args, - xmlrpc_value ** const valPP, - const char ** const tailP) { - - const char * formatCursor; - va_list args_copy; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(format != NULL); - - if (strlen(format) == 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Format string is empty."); - else { - formatCursor = &format[0]; - VA_LIST_COPY(args_copy, args); - getValue(envP, &formatCursor, &args_copy, valPP); - - if (!envP->fault_occurred) - XMLRPC_ASSERT_VALUE_OK(*valPP); - - *tailP = formatCursor; - } -} - - - -xmlrpc_value * -xmlrpc_build_value(xmlrpc_env * const envP, - const char * const format, - ...) { - - va_list args; - xmlrpc_value* retval; - const char * suffix; - - va_start(args, format); - xmlrpc_build_value_va(envP, format, args, &retval, &suffix); - va_end(args); - - if (!envP->fault_occurred) { - if (*suffix != '\0') - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument " - "specifier: '%s'. There must be exactly one arument.", - suffix); - - if (envP->fault_occurred) - xmlrpc_DECREF(retval); - } - return retval; -} - - -/*========================================================================= -** Parsing XML-RPC values. -**========================================================================= -** Parse an XML-RPC value based on a format string. This code is heavily -** inspired by Py_BuildValue from Python 1.5.2. -*/ - -/* Prototype for recursive invocation: */ - -static void -parsevalue(xmlrpc_env * const env, - xmlrpc_value * const val, - const char ** const format, - va_list * args); - -static void -parsearray(xmlrpc_env * const env, - const xmlrpc_value * const array, - const char ** const format, - char const delimiter, - va_list * args) { - - int size, i; - xmlrpc_value *item; - - /* Fetch the array size. */ - size = xmlrpc_array_size(env, array); - XMLRPC_FAIL_IF_FAULT(env); - - /* Loop over the items in the array. */ - for (i = 0; i < size; i++) { - /* Bail out if the caller didn't care about the rest of the items. */ - if (**format == '*') - break; - - item = xmlrpc_array_get_item(env, array, i); - XMLRPC_FAIL_IF_FAULT(env); - - XMLRPC_ASSERT(**format != '\0'); - if (**format == delimiter) - XMLRPC_FAIL(env, XMLRPC_INDEX_ERROR, "Too many items in array"); - parsevalue(env, item, format, args); - XMLRPC_FAIL_IF_FAULT(env); - } - if (**format == '*') - (*format)++; - if (**format != delimiter) - XMLRPC_FAIL(env, XMLRPC_INDEX_ERROR, "Not enough items in array"); - - cleanup: - return; -} - - - -static void -parsestruct(xmlrpc_env * const env, - xmlrpc_value * const strct, - const char ** const format, - char const delimiter, - va_list * args) { - - xmlrpc_value *key, *value; - char *keystr; - size_t keylen; - - /* Set up error handling preconditions. */ - key = NULL; - - /* Build the members of our struct. */ - while (**format != '*' && **format != delimiter && **format != '\0') { - - /* Get our key, and skip over the ':' character. Notice the - ** sudden call to getValue--we're going in the opposite direction. */ - getValue(env, format, args, &key); - XMLRPC_FAIL_IF_FAULT(env); - XMLRPC_ASSERT(**format == ':'); - (*format)++; - - /* Look up the value for our key. */ - xmlrpc_parse_value(env, key, "s#", &keystr, &keylen); - XMLRPC_FAIL_IF_FAULT(env); - value = xmlrpc_struct_get_value_n(env, strct, keystr, keylen); - XMLRPC_FAIL_IF_FAULT(env); - - /* Get our value, and skip over the ',' character (if present). */ - parsevalue(env, value, format, args); - XMLRPC_FAIL_IF_FAULT(env); - XMLRPC_ASSERT(**format == ',' || **format == delimiter); - if (**format == ',') - (*format)++; - - /* Release our reference, and restore our invariant. */ - xmlrpc_DECREF(key); - key = NULL; - } - if (**format == '*') { - (*format)++; - if (**format != delimiter && **format != '\0') - XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, - "* can appear only at the end " - "of a structure format specifier"); - } else { - /* Here we're supposed to fail if he didn't extract all the - members. But we don't know how to determine whether he - specified all the members, so we always fail. - */ - XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, "You must specify '*' as the " - "last member of a structure in a format specifier " - "used for parsing an xmlrpc_value"); - } - XMLRPC_ASSERT(**format == delimiter || **format == '\0'); - -cleanup: - if (key) - xmlrpc_DECREF(key); -} - - -static void -parsevalue(xmlrpc_env * const envP, - xmlrpc_value * const valueP, - const char ** const format, - va_list * args) { - - char formatSpecChar; - - formatSpecChar = *(*format)++; - - switch (formatSpecChar) { - case 'i': - validateType(envP, valueP, XMLRPC_TYPE_INT); - if (!envP->fault_occurred) { - xmlrpc_int32 * const int32ptr = - (xmlrpc_int32*) va_arg(*args, xmlrpc_int32*); - *int32ptr = valueP->_value.i; - } - break; - - case 'b': - validateType(envP, valueP, XMLRPC_TYPE_BOOL); - if (!envP->fault_occurred) { - xmlrpc_bool * const boolptr = - (xmlrpc_bool*) va_arg(*args, xmlrpc_bool*); - *boolptr = valueP->_value.b; - } - break; - - case 'd': - validateType(envP, valueP, XMLRPC_TYPE_DOUBLE); - if (!envP->fault_occurred) { - double * const doubleptr = (double*) va_arg(*args, double*); - *doubleptr = valueP->_value.d; - } - break; - - case 's': - validateType(envP, valueP, XMLRPC_TYPE_STRING); - if (!envP->fault_occurred) { - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - size_t const len = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1; - - char ** const strptr = (char**) va_arg(*args, char**); - if (**format == '#') { - size_t * const sizeptr = (size_t*) va_arg(*args, size_t**); - (*format)++; - *sizeptr = len; - } else - verifyNoNulls(envP, contents, (unsigned int)len); - *strptr = contents; - } - break; - -#ifdef HAVE_UNICODE_WCHAR - case 'w': - validateType(envP, valueP, XMLRPC_TYPE_STRING); - if (!envP->fault_occurred) { - if (!valueP->_wcs_block) { - /* Allocate a wchar_t string if we don't have one. */ - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - size_t const len = - XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1; - valueP->_wcs_block = - xmlrpc_utf8_to_wcs(envP, contents, len + 1); - } - if (!envP->fault_occurred) { - wchar_t * const wcontents = - XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block); - size_t const len = - XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1; - - wchar_t ** const wcsptr = (wchar_t**) va_arg(*args, wchar_t**); - if (**format == '#') { - size_t * const sizeptr = (size_t*) va_arg(*args, size_t**); - (*format)++; - *sizeptr = len; - } else - verifyNoNullsW(envP, wcontents, (unsigned int)len); - *wcsptr = wcontents; - } - } - break; -#endif /* HAVE_UNICODE_WCHAR */ - - case '8': - /* The code 't' is reserved for a better, time_t based - ** implementation of dateTime conversion. */ - validateType(envP, valueP, XMLRPC_TYPE_DATETIME); - if (!envP->fault_occurred) { - char * const contents = - XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); - char ** const strptr = (char**) va_arg(*args, char**); - *strptr = contents; - } - break; - - case '6': - validateType(envP, valueP, XMLRPC_TYPE_BASE64); - if (!envP->fault_occurred) { - unsigned char * const bin_data = - XMLRPC_MEMBLOCK_CONTENTS(unsigned char, - &valueP->_block); - size_t const len = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block); - unsigned char ** const binptr = - (unsigned char**) va_arg(*args, unsigned char**); - size_t * const sizeptr = (size_t*) va_arg(*args, size_t**); - *binptr = bin_data; - *sizeptr = len; - } - break; - - case 'p': - validateType(envP, valueP, XMLRPC_TYPE_C_PTR); - if (!envP->fault_occurred) { - void ** const voidptrptr = (void**) va_arg(*args, void**); - *voidptrptr = valueP->_value.c_ptr; - } - break; - - case 'V': { - xmlrpc_value ** const valptr = - (xmlrpc_value**) va_arg(*args, xmlrpc_value**); - *valptr = valueP; - } - break; - - case 'A': - validateType(envP, valueP, XMLRPC_TYPE_ARRAY); - if (!envP->fault_occurred) { - xmlrpc_value ** const valptr = - (xmlrpc_value**) va_arg(*args, xmlrpc_value**); - *valptr = valueP; - } - break; - - case 'S': - validateType(envP, valueP, XMLRPC_TYPE_STRUCT); - if (!envP->fault_occurred) { - xmlrpc_value ** const valptr = - (xmlrpc_value**) va_arg(*args, xmlrpc_value**); - *valptr = valueP; - } - break; - - case '(': - validateType(envP, valueP, XMLRPC_TYPE_ARRAY); - if (!envP->fault_occurred) { - parsearray(envP, valueP, format, ')', args); - (*format)++; - } - break; - - case '{': - validateType(envP, valueP, XMLRPC_TYPE_STRUCT); - if (!envP->fault_occurred) { - parsestruct(envP, valueP, format, '}', args); - (*format)++; - } - break; - - default: - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, "Invalid format character '%c'", - formatSpecChar); - } -} - - - -void -xmlrpc_parse_value_va(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - va_list args) { - - const char *format_copy; - va_list args_copy; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(value); - XMLRPC_ASSERT(format != NULL); - - format_copy = format; - VA_LIST_COPY(args_copy, args); - parsevalue(envP, value, &format_copy, &args_copy); - if (!envP->fault_occurred) { - XMLRPC_ASSERT(*format_copy == '\0'); - } -} - - - -void -xmlrpc_parse_value(xmlrpc_env * const envP, - xmlrpc_value * const value, - const char * const format, - ...) { - - va_list args; - - va_start(args, format); - xmlrpc_parse_value_va(envP, value, format, args); - va_end(args); -} - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ diff --git a/Utilities/cmxmlrpc/xmlrpc_expat.c b/Utilities/cmxmlrpc/xmlrpc_expat.c deleted file mode 100644 index d7b6e19806..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_expat.c +++ /dev/null @@ -1,390 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_xmlparser.h" - -/* Define the contents of our internal structure. */ -struct _xml_element { - struct _xml_element *_parent; - char *_name; - xmlrpc_mem_block _cdata; /* char */ - xmlrpc_mem_block _children; /* xml_element* */ -}; - -/* Check that we're using expat in UTF-8 mode, not wchar_t mode. -** If you need to use expat in wchar_t mode, write a subroutine to -** copy a wchar_t string to a char string & return an error for -** any non-ASCII characters. Then call this subroutine on all -** XML_Char strings passed to our event handlers before using the -** data. */ -/* #if sizeof(char) != sizeof(XML_Char) -** #error expat must define XML_Char to be a regular char. -** #endif -*/ - -#define XMLRPC_ASSERT_ELEM_OK(elem) \ - XMLRPC_ASSERT((elem) != NULL && (elem)->_name != XMLRPC_BAD_POINTER) - - -/*========================================================================= -** xml_element_new -**========================================================================= -** Create a new xml_element. This routine isn't exported, because the -** arguments are implementation-dependent. -*/ - -static xml_element *xml_element_new (xmlrpc_env *env, char *name) -{ - xml_element *retval; - int name_valid, cdata_valid, children_valid; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(name != NULL); - - /* Set up our error-handling preconditions. */ - name_valid = cdata_valid = children_valid = 0; - - /* Allocate our xml_element structure. */ - retval = (xml_element*) malloc(sizeof(xml_element)); - XMLRPC_FAIL_IF_NULL(retval, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - - /* Set our parent field to NULL. */ - retval->_parent = NULL; - - /* Copy over the element name. */ - retval->_name = (char*) malloc(strlen(name) + 1); - XMLRPC_FAIL_IF_NULL(retval->_name, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - name_valid = 1; - strcpy(retval->_name, name); - - /* Initialize a block to hold our CDATA. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(char, env, &retval->_cdata, 0); - XMLRPC_FAIL_IF_FAULT(env); - cdata_valid = 1; - - /* Initialize a block to hold our child elements. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element*, env, &retval->_children, 0); - XMLRPC_FAIL_IF_FAULT(env); - children_valid = 1; - - cleanup: - if (env->fault_occurred) { - if (retval) { - if (name_valid) - free(retval->_name); - if (cdata_valid) - xmlrpc_mem_block_clean(&retval->_cdata); - if (children_valid) - xmlrpc_mem_block_clean(&retval->_children); - free(retval); - } - return NULL; - } else { - return retval; - } -} - - -/*========================================================================= -** xml_element_free -**========================================================================= -** Blow away an existing element & all of its child elements. -*/ - -void xml_element_free (xml_element *elem) -{ - xmlrpc_mem_block *children; - int size, i; - xml_element **contents; - - XMLRPC_ASSERT_ELEM_OK(elem); - - free(elem->_name); - elem->_name = XMLRPC_BAD_POINTER; - xmlrpc_mem_block_clean(&elem->_cdata); - - /* Deallocate all of our children recursively. */ - children = &elem->_children; - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element*, children); - size = (int)XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element*, children); - for (i = 0; i < size; i++) - xml_element_free(contents[i]); - - xmlrpc_mem_block_clean(&elem->_children); - free(elem); -} - - -/*========================================================================= -** Miscellaneous Accessors -**========================================================================= -** Return the fields of the xml_element. See the header for more -** documentation on each function works. -*/ - -char *xml_element_name (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return elem->_name; -} - -/* The result of this function is NOT VALID until the end_element handler -** has been called! */ -size_t xml_element_cdata_size (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elem->_cdata) - 1; -} - -char *xml_element_cdata (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elem->_cdata); -} - -size_t xml_element_children_size (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element*, &elem->_children); -} - -xml_element **xml_element_children (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element*, &elem->_children); -} - - -/*========================================================================= -** Internal xml_element Utility Functions -**========================================================================= -*/ - -static void xml_element_append_cdata (xmlrpc_env *env, - xml_element *elem, - char *cdata, - size_t size) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, &elem->_cdata, cdata, size); -} - -/* Whether or not this function succeeds, it takes ownership of the 'child' -** argument. -** WARNING - This is the exact opposite of the usual memory ownership -** rules for xmlrpc_value! So please pay attention. */ -static void xml_element_append_child (xmlrpc_env *env, - xml_element *elem, - xml_element *child) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); - XMLRPC_ASSERT_ELEM_OK(child); - XMLRPC_ASSERT(child->_parent == NULL); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element*, env, &elem->_children, - &child, 1); - if (!env->fault_occurred) - child->_parent = elem; - else - xml_element_free(child); -} - - -/*========================================================================= -** Our parse context. We pass this around as expat user data. -**========================================================================= -*/ - -typedef struct { - xmlrpc_env *env; - xml_element *root; - xml_element *current; -} parse_context; - - -/*========================================================================= -** Expat Event Handler Functions -**========================================================================= -*/ - -static void -start_element (void *user_data, XML_Char *name, XML_Char **atts ATTR_UNUSED) -{ - parse_context *context; - xml_element *elem, *new_current; - - XMLRPC_ASSERT(user_data != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - /* Build a new element. */ - elem = xml_element_new(context->env, name); - XMLRPC_FAIL_IF_FAULT(context->env); - - /* Insert it in the appropriate place. */ - if (!context->root) { - context->root = elem; - context->current = elem; - elem = NULL; - } else { - XMLRPC_ASSERT(context->current != NULL); - - /* (We need to watch our error handling invariants very carefully - ** here. Read the docs for xml_element_append_child. */ - new_current = elem; - xml_element_append_child(context->env, context->current, elem); - elem = NULL; - XMLRPC_FAIL_IF_FAULT(context->env); - context->current = new_current; - } - - cleanup: - if (elem) - xml_element_free(elem); - } -} - -static void end_element (void *user_data, XML_Char *name) -{ - parse_context *context; - - XMLRPC_ASSERT(user_data != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - /* XXX - I think expat enforces these facts, but I want to be sure. - ** If one of these assertion ever fails, it should be replaced by a - ** non-assertion runtime error check. */ - XMLRPC_ASSERT(strcmp(name, context->current->_name) == 0); - XMLRPC_ASSERT(context->current->_parent != NULL || - context->current == context->root); - - /* Add a trailing '\0' to our cdata. */ - xml_element_append_cdata(context->env, context->current, "\0", 1); - XMLRPC_FAIL_IF_FAULT(context->env); - - /* Pop our "stack" of elements. */ - context->current = context->current->_parent; - - cleanup: - return; - } -} - -static void character_data (void *user_data, XML_Char *s, int len) -{ - parse_context *context; - - XMLRPC_ASSERT(user_data != NULL && s != NULL && len >= 0); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - XMLRPC_ASSERT(context->current != NULL); - - xml_element_append_cdata(context->env, context->current, s, len); - XMLRPC_FAIL_IF_FAULT(context->env); - - cleanup: - return; - } -} - - -/*========================================================================= -** Expat Driver -**========================================================================= -** XXX - We should allow the user to specify the encoding of our xml_data. -*/ - -xml_element *xml_parse (xmlrpc_env *env, const char *xml_data, int xml_len) -{ - parse_context context; - XML_Parser parser; - int ok; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(xml_data != NULL && xml_len >= 0); - - /* Set up our error-handling preconditions. */ - context.root = NULL; - - /* Set up the rest of our parse context. */ - context.env = env; - context.current = NULL; - - /* Set up our XML parser. */ - parser = XML_ParserCreate(NULL); - XMLRPC_FAIL_IF_NULL(parser, env, XMLRPC_INTERNAL_ERROR, - "Could not create expat parser"); - XML_SetUserData(parser, &context); - XML_SetElementHandler(parser, - (XML_StartElementHandler) start_element, - (XML_EndElementHandler) end_element); - XML_SetCharacterDataHandler(parser, - (XML_CharacterDataHandler) character_data); - - /* Parse our data. */ - ok = XML_Parse(parser, xml_data, xml_len, 1); - if (!ok) - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, - (char*) XML_ErrorString(XML_GetErrorCode(parser))); - XMLRPC_FAIL_IF_FAULT(env); - - /* Perform some sanity checks. */ - XMLRPC_ASSERT(context.root != NULL); - XMLRPC_ASSERT(context.current == NULL); - - cleanup: - if (parser) - XML_ParserFree(parser); - - if (env->fault_occurred) { - if (context.root) - xml_element_free(context.root); - return NULL; - } else { - return context.root; - } -} diff --git a/Utilities/cmxmlrpc/xmlrpc_int.h b/Utilities/cmxmlrpc/xmlrpc_int.h deleted file mode 100644 index 3abb6d3317..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_int.h +++ /dev/null @@ -1,112 +0,0 @@ -/*============================================================================ - xmlrpc_client_int.h -============================================================================== - This header file defines the interface between modules inside - xmlrpc-c. - - Use this in addition to xmlrpc.h, which defines the external - interface. - - Copyright information is at the end of the file. -============================================================================*/ - - -#ifndef _XMLRPC_INT_H_ -#define _XMLRPC_INT_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -struct _xmlrpc_value { - xmlrpc_type _type; - int _refcount; - - /* Certain data types store their data directly in the xmlrpc_value. */ - union { - xmlrpc_int32 i; - xmlrpc_bool b; - double d; - /* time_t t */ - void *c_ptr; - } _value; - - /* Other data types use a memory block. */ - xmlrpc_mem_block _block; - -#ifdef HAVE_UNICODE_WCHAR - /* We may need to convert our string data to a wchar_t string. */ - xmlrpc_mem_block *_wcs_block; -#endif -}; - -typedef struct { - unsigned char key_hash; - xmlrpc_value *key; - xmlrpc_value *value; -} _struct_member; - - -struct _xmlrpc_registry { - int _introspection_enabled; - xmlrpc_value *_methods; - xmlrpc_value *_default_method; - xmlrpc_value *_preinvoke_method; -}; - - -/* When we deallocate a pointer in a struct, we often replace it with -** this and throw in a few assertions here and there. */ -#define XMLRPC_BAD_POINTER ((void*) 0xDEADBEEF) - - -void -xmlrpc_traceXml(const char * const label, - const char * const xml, - unsigned int const xmlLength); - -void -xmlrpc_destroyStruct(xmlrpc_value * const structP); - -void -xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP); - -const char * -xmlrpc_makePrintable(const char * const input); - -const char * -xmlrpc_makePrintableChar(char const input); - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_libxml2.c b/Utilities/cmxmlrpc/xmlrpc_libxml2.c deleted file mode 100644 index eb3ed721ab..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_libxml2.c +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2002 Ximian, Inc. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_xmlparser.h" - -/* Define the contents of our internal structure. */ -struct _xml_element { - struct _xml_element *_parent; - char *_name; - xmlrpc_mem_block _cdata; /* char */ - xmlrpc_mem_block _children; /* xml_element* */ -}; - -#define XMLRPC_ASSERT_ELEM_OK(elem) \ - XMLRPC_ASSERT((elem) != NULL && (elem)->_name != XMLRPC_BAD_POINTER) - - -/*========================================================================= -** xml_element_new -**========================================================================= -** Create a new xml_element. This routine isn't exported, because the -** arguments are implementation-dependent. -*/ - -static xml_element *xml_element_new (xmlrpc_env *env, char *name) -{ - xml_element *retval; - int name_valid, cdata_valid, children_valid; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(name != NULL); - - /* Set up our error-handling preconditions. */ - retval = NULL; - name_valid = cdata_valid = children_valid = 0; - - /* Allocate our xml_element structure. */ - retval = (xml_element*) malloc(sizeof(xml_element)); - XMLRPC_FAIL_IF_NULL(retval, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - - /* Set our parent field to NULL. */ - retval->_parent = NULL; - - /* Copy over the element name. */ - retval->_name = (char*) malloc(strlen(name) + 1); - XMLRPC_FAIL_IF_NULL(retval->_name, env, XMLRPC_INTERNAL_ERROR, - "Couldn't allocate memory for XML element"); - name_valid = 1; - strcpy(retval->_name, name); - - /* Initialize a block to hold our CDATA. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(char, env, &retval->_cdata, 0); - XMLRPC_FAIL_IF_FAULT(env); - cdata_valid = 1; - - /* Initialize a block to hold our child elements. */ - XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element*, env, &retval->_children, 0); - XMLRPC_FAIL_IF_FAULT(env); - children_valid = 1; - - cleanup: - if (env->fault_occurred) { - if (retval) { - if (name_valid) - free(retval->_name); - if (cdata_valid) - xmlrpc_mem_block_clean(&retval->_cdata); - if (children_valid) - xmlrpc_mem_block_clean(&retval->_children); - free(retval); - } - return NULL; - } else { - return retval; - } -} - - -/*========================================================================= -** xml_element_free -**========================================================================= -** Blow away an existing element & all of its child elements. -*/ - -void xml_element_free (xml_element *elem) -{ - xmlrpc_mem_block *children; - int size, i; - xml_element **contents; - - XMLRPC_ASSERT_ELEM_OK(elem); - - free(elem->_name); - elem->_name = XMLRPC_BAD_POINTER; - xmlrpc_mem_block_clean(&elem->_cdata); - - /* Deallocate all of our children recursively. */ - children = &elem->_children; - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element*, children); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element*, children); - for (i = 0; i < size; i++) - xml_element_free(contents[i]); - - xmlrpc_mem_block_clean(&elem->_children); - free(elem); -} - - -/*========================================================================= -** Miscellaneous Accessors -**========================================================================= -** Return the fields of the xml_element. See the header for more -** documentation on each function works. -*/ - -char *xml_element_name (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return elem->_name; -} - -/* The result of this function is NOT VALID until the end_element handler -** has been called! */ -size_t xml_element_cdata_size (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elem->_cdata) - 1; -} - -char *xml_element_cdata (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elem->_cdata); -} - -size_t xml_element_children_size (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element*, &elem->_children); -} - -xml_element **xml_element_children (xml_element *elem) -{ - XMLRPC_ASSERT_ELEM_OK(elem); - return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element*, &elem->_children); -} - - -/*========================================================================= -** Internal xml_element Utility Functions -**========================================================================= -*/ - -static void xml_element_append_cdata (xmlrpc_env *env, - xml_element *elem, - char *cdata, - size_t size) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, &elem->_cdata, cdata, size); -} - -/* Whether or not this function succeeds, it takes ownership of the 'child' -** argument. -** WARNING - This is the exact opposite of the usual memory ownership -** rules for xmlrpc_value! So please pay attention. */ -static void xml_element_append_child (xmlrpc_env *env, - xml_element *elem, - xml_element *child) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_ELEM_OK(elem); - XMLRPC_ASSERT_ELEM_OK(child); - XMLRPC_ASSERT(child->_parent == NULL); - - XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element*, env, &elem->_children, - &child, 1); - if (!env->fault_occurred) - child->_parent = elem; - else - xml_element_free(child); -} - - -/*========================================================================= -** Our parse context. We pass this around as libxml user data. -**========================================================================= -*/ - -typedef struct { - xmlrpc_env *env; - xml_element *root; - xml_element *current; -} parse_context; - - -/*========================================================================= -** LibXML Event Handler Functions -**========================================================================= -*/ - -static void -start_element (void *user_data, const xmlChar *name, const xmlChar **attrs) -{ - parse_context *context; - xml_element *elem, *new_current; - - XMLRPC_ASSERT(user_data != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - /* Set up our error-handling preconditions. */ - elem = NULL; - - /* Build a new element. */ - elem = xml_element_new(context->env, (char *) name); - XMLRPC_FAIL_IF_FAULT(context->env); - - /* Insert it in the appropriate place. */ - if (!context->root) { - context->root = elem; - context->current = elem; - elem = NULL; - } else { - XMLRPC_ASSERT(context->current != NULL); - - /* (We need to watch our error handling invariants very carefully - ** here. Read the docs for xml_element_append_child. */ - new_current = elem; - xml_element_append_child(context->env, context->current, elem); - elem = NULL; - XMLRPC_FAIL_IF_FAULT(context->env); - context->current = new_current; - } - - cleanup: - if (elem) - xml_element_free(elem); - } -} - -static void -end_element (void *user_data, const xmlChar *name) -{ - parse_context *context; - - XMLRPC_ASSERT(user_data != NULL && name != NULL); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - /* XXX - I think expat enforces these facts, but I want to be sure. - ** If one of these assertion ever fails, it should be replaced by a - ** non-assertion runtime error check. */ - XMLRPC_ASSERT(strcmp(name, context->current->_name) == 0); - XMLRPC_ASSERT(context->current->_parent != NULL || - context->current == context->root); - - /* Add a trailing '\0' to our cdata. */ - xml_element_append_cdata(context->env, context->current, "\0", 1); - XMLRPC_FAIL_IF_FAULT(context->env); - - /* Pop our "stack" of elements. */ - context->current = context->current->_parent; - - cleanup: - return; - } -} - -static void character_data (void *user_data, const xmlChar *s, int len) -{ - parse_context *context; - - XMLRPC_ASSERT(user_data != NULL && s != NULL && len >= 0); - - /* Get our context and see if an error has already occured. */ - context = (parse_context*) user_data; - if (!context->env->fault_occurred) { - - XMLRPC_ASSERT(context->current != NULL); - - xml_element_append_cdata(context->env, context->current, (char *) s, len); - XMLRPC_FAIL_IF_FAULT(context->env); - - cleanup: - return; - } -} - - -/*========================================================================= -** LibXML Driver -**========================================================================= -** XXX - We should allow the user to specify the encoding of our xml_data. -*/ - -static xmlSAXHandler sax_handler = { - NULL, /* internalSubset */ - NULL, /* isStandalone */ - NULL, /* hasInternalSubset */ - NULL, /* hasExternalSubset */ - NULL, /* resolveEntity */ - NULL, /* getEntity */ - NULL, /* entityDecl */ - NULL, /* notationDecl */ - NULL, /* attributeDecl */ - NULL, /* elementDecl */ - NULL, /* unparsedEntityDecl */ - NULL, /* setDocumentLocator */ - NULL, /* startDocument */ - NULL, /* endDocument */ - start_element, /* startElement */ - end_element, /* endElement */ - NULL, /* reference */ - character_data, /* characters */ - NULL, /* ignorableWhitespace */ - NULL, /* processingInstruction */ - NULL, /* comment */ - NULL, /* warning */ - NULL, /* error */ - NULL, /* fatalError */ -}; - -xml_element *xml_parse (xmlrpc_env *env, char *xml_data, int xml_len) -{ - parse_context context; - xmlParserCtxt *parser; - int err; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(xml_data != NULL && xml_len >= 0); - - /* Set up our error-handling preconditions. */ - parser = NULL; - context.root = NULL; - - /* Set up the rest of our parse context. */ - context.env = env; - context.current = NULL; - - /* Set up our XML parser. */ - parser = xmlCreatePushParserCtxt(&sax_handler, &context, NULL, 0, NULL); - XMLRPC_FAIL_IF_NULL(parser, env, XMLRPC_INTERNAL_ERROR, - "Could not create expat parser"); - - /* Parse our data. */ - err = xmlParseChunk(parser, xml_data, xml_len, 1); - if (err) - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, "XML parsing failed"); - XMLRPC_FAIL_IF_FAULT(env); - - /* Perform some sanity checks. */ - XMLRPC_ASSERT(context.root != NULL); - XMLRPC_ASSERT(context.current == NULL); - - cleanup: - if (parser) - xmlFreeParserCtxt(parser); - - if (env->fault_occurred) { - if (context.root) - xml_element_free(context.root); - return NULL; - } else { - return context.root; - } -} diff --git a/Utilities/cmxmlrpc/xmlrpc_parse.c b/Utilities/cmxmlrpc/xmlrpc_parse.c deleted file mode 100644 index 0999eb6811..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_parse.c +++ /dev/null @@ -1,767 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_xmlparser.h" - - -/*========================================================================= -** Data Format -**========================================================================= -** All XML-RPC documents contain a single methodCall or methodResponse -** element. -** -** methodCall methodName, params -** methodResponse (params|fault) -** params param* -** param value -** fault value -** value (i4|int|boolean|string|double|dateTime.iso8601|base64| -** struct|array) -** array data -** data value* -** struct member* -** member name, value -** -** Contain CDATA: methodName, i4, int, boolean, string, double, -** dateTime.iso8601, base64, name -** -** We attempt to validate the structure of the XML document carefully. -** We also try *very* hard to handle malicious data gracefully, and without -** leaking memory. -** -** The CHECK_NAME and CHECK_CHILD_COUNT macros examine an XML element, and -** invoke XMLRPC_FAIL if something looks wrong. -*/ - -#define CHECK_NAME(env,elem,name) \ - do \ - if (strcmp((name), xml_element_name(elem)) != 0) \ - XMLRPC_FAIL2(env, XMLRPC_PARSE_ERROR, \ - "Expected element of type <%s>, found <%s>", \ - (name), xml_element_name(elem)); \ - while (0) - -#define CHECK_CHILD_COUNT(env,elem,count) \ - do \ - if (xml_element_children_size(elem) != (count)) \ - XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, \ - "Expected <%s> to have %d children, found %d", \ - xml_element_name(elem), (count), \ - xml_element_children_size(elem)); \ - while (0) - -static xml_element * -get_child_by_name (xmlrpc_env *env, xml_element *parent, char *name) -{ - size_t child_count, i; - xml_element **children; - - children = xml_element_children(parent); - child_count = xml_element_children_size(parent); - for (i = 0; i < child_count; i++) { - if (0 == strcmp(xml_element_name(children[i]), name)) - return children[i]; - } - - xmlrpc_env_set_fault_formatted(env, XMLRPC_PARSE_ERROR, - "Expected <%s> to have child <%s>", - xml_element_name(parent), name); - return NULL; -} - - -/*========================================================================= -** Number-Parsing Functions -**========================================================================= -** These functions mirror atoi, atof, etc., but provide better -** error-handling. These routines may reset errno to zero. -*/ - -static xmlrpc_int32 -xmlrpc_atoi(xmlrpc_env *env, char *str, size_t stringLength, - xmlrpc_int32 min, xmlrpc_int32 max) -{ - long i; - char *end; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(str); - - /* Suppress compiler warnings. */ - i = 0; - - /* Check for leading white space. */ - if (isspace((int)(str[0]))) - XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR, - "\"%s\" must not contain whitespace", str); - - /* Convert the value. */ - end = str + stringLength; - errno = 0; - i = strtol(str, &end, 10); - - /* Look for ERANGE. */ - if (errno != 0) - /* XXX - Do all operating systems have thread-safe strerror? */ - XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, - "error parsing \"%s\": %s (%d)", - str, strerror(errno), errno); - - /* Look for out-of-range errors which didn't produce ERANGE. */ - if (i < min || i > max) - XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, - "\"%s\" must be in range %d to %d", str, min, max); - - /* Check for unused characters. */ - if (end != str + stringLength) - XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR, - "\"%s\" contained trailing data", str); - - cleanup: - errno = 0; - if (env->fault_occurred) - return 0; - return (xmlrpc_int32) i; -} - - - -static double -xmlrpc_atod(xmlrpc_env *env, char *str, size_t stringLength) -{ - double d; - char *end; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(str); - - /* Suppress compiler warnings. */ - d = 0.0; - - /* Check for leading white space. */ - if (isspace((int)(str[0]))) - XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR, - "\"%s\" must not contain whitespace", str); - - /* Convert the value. */ - end = str + stringLength; - errno = 0; - d = strtod(str, &end); - - /* Look for ERANGE. */ - if (errno != 0) - /* XXX - Do all operating systems have thread-safe strerror? */ - XMLRPC_FAIL3(env, XMLRPC_PARSE_ERROR, - "error parsing \"%s\": %s (%d)", - str, strerror(errno), errno); - - /* Check for unused characters. */ - if (end != str + stringLength) - XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR, - "\"%s\" contained trailing data", str); - - cleanup: - errno = 0; - if (env->fault_occurred) - return 0.0; - return d; -} - - -/*========================================================================= -** make_string -**========================================================================= -** Make an XML-RPC string. -** -** SECURITY: We validate our UTF-8 first. This incurs a performance -** penalty, but ensures that we will never pass maliciously malformed -** UTF-8 data back up to the user layer, where it could wreak untold -** damange. Don't comment out this check unless you know *exactly* what -** you're doing. (Win32 developers who remove this check are *begging* -** to wind up on BugTraq, because many of the Win32 filesystem routines -** rely on an insecure UTF-8 decoder.) -** -** XXX - This validation is redundant if the user chooses to convert -** UTF-8 data into a wchar_t string. -*/ - -static xmlrpc_value * -make_string(xmlrpc_env *env, char *cdata, size_t cdata_size) -{ -#ifdef HAVE_UNICODE_WCHAR - xmlrpc_validate_utf8(env, cdata, cdata_size); -#endif - - if (env->fault_occurred) - return NULL; - return xmlrpc_build_value(env, "s#", cdata, cdata_size); -} - - - -/*========================================================================= -** convert_value -**========================================================================= -** Convert an XML element representing a value into an xmlrpc_value. -*/ - -static xmlrpc_value * -convert_array (xmlrpc_env *env, unsigned *depth, xml_element *elem); -static xmlrpc_value * -convert_struct(xmlrpc_env *env, unsigned *depth, xml_element *elem); - - - -static xmlrpc_value * -convert_value(xmlrpc_env *env, unsigned *depth, xml_element *elem) -{ - xml_element *child; - size_t child_count; - char *cdata, *child_name; - size_t cdata_size, ascii_len; - xmlrpc_mem_block *decoded; - unsigned char *ascii_data; - xmlrpc_value *retval; - xmlrpc_int32 i; - double d; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(elem != NULL); - - /* Error-handling precoditions. - ** If we haven't changed any of these from their default state, we're - ** allowed to tail-call xmlrpc_build_value. */ - retval = NULL; - decoded = NULL; - - /* Make sure we haven't recursed too deeply. */ - if (*depth > xmlrpc_limit_get(XMLRPC_NESTING_LIMIT_ID)) - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, - "Nested data structure too deep."); - - /* Validate our structure, and see whether we have a child element. */ - CHECK_NAME(env, elem, "value"); - child_count = xml_element_children_size(elem); - - if (child_count == 0) { - /* We have no type element, so treat the value as a string. */ - cdata = xml_element_cdata(elem); - cdata_size = xml_element_cdata_size(elem); - return make_string(env, cdata, cdata_size); - } else { - /* We should have a type tag inside our value tag. */ - CHECK_CHILD_COUNT(env, elem, 1); - child = xml_element_children(elem)[0]; - - /* Parse our value-containing element. */ - child_name = xml_element_name(child); - if (strcmp(child_name, "struct") == 0) { - return convert_struct(env, depth, child); - } else if (strcmp(child_name, "array") == 0) { - CHECK_CHILD_COUNT(env, child, 1); - return convert_array(env, depth, child); - } else { - CHECK_CHILD_COUNT(env, child, 0); - cdata = xml_element_cdata(child); - cdata_size = xml_element_cdata_size(child); - if (strcmp(child_name, "i4") == 0 || - strcmp(child_name, "int") == 0) - { - i = xmlrpc_atoi(env, cdata, strlen(cdata), - XMLRPC_INT32_MIN, XMLRPC_INT32_MAX); - XMLRPC_FAIL_IF_FAULT(env); - return xmlrpc_build_value(env, "i", i); - } else if (strcmp(child_name, "string") == 0) { - return make_string(env, cdata, cdata_size); - } else if (strcmp(child_name, "boolean") == 0) { - i = xmlrpc_atoi(env, cdata, strlen(cdata), 0, 1); - XMLRPC_FAIL_IF_FAULT(env); - return xmlrpc_build_value(env, "b", (xmlrpc_bool) i); - } else if (strcmp(child_name, "double") == 0) { - d = xmlrpc_atod(env, cdata, strlen(cdata)); - XMLRPC_FAIL_IF_FAULT(env); - return xmlrpc_build_value(env, "d", d); - } else if (strcmp(child_name, "dateTime.iso8601") == 0) { - return xmlrpc_build_value(env, "8", cdata); - } else if (strcmp(child_name, "base64") == 0) { - /* No more tail calls once we do this! */ - decoded = xmlrpc_base64_decode(env, cdata, cdata_size); - XMLRPC_FAIL_IF_FAULT(env); - ascii_data = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char, - decoded); - ascii_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(unsigned char, - decoded); - retval = xmlrpc_build_value(env, "6", ascii_data, ascii_len); - XMLRPC_FAIL_IF_FAULT(env); - } else { - XMLRPC_FAIL1(env, XMLRPC_PARSE_ERROR, - "Unknown value type <%s>", child_name); - } - } - } - - cleanup: - if (decoded) - xmlrpc_mem_block_free(decoded); - if (env->fault_occurred) { - if (retval) - xmlrpc_DECREF(retval); - return NULL; - } - return retval; -} - - - -/*========================================================================= -** convert_array -**========================================================================= -** Convert an XML element representing an array into an xmlrpc_value. -*/ - -static xmlrpc_value * -convert_array(xmlrpc_env *env, unsigned *depth, xml_element *elem) -{ - xml_element *data, **values, *value; - xmlrpc_value *array, *item; - size_t size, i; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(elem != NULL); - - /* Set up our error-handling preconditions. */ - item = NULL; - (*depth)++; - - /* Allocate an array to hold our values. */ - array = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - - /* We don't need to check our element name--our callers do that. */ - CHECK_CHILD_COUNT(env, elem, 1); - data = xml_element_children(elem)[0]; - CHECK_NAME(env, data, "data"); - - /* Iterate over our children. */ - values = xml_element_children(data); - size = xml_element_children_size(data); - for (i = 0; i < size; i++) { - value = values[i]; - item = convert_value(env, depth, value); - XMLRPC_FAIL_IF_FAULT(env); - - xmlrpc_array_append_item(env, array, item); - xmlrpc_DECREF(item); - item = NULL; - XMLRPC_FAIL_IF_FAULT(env); - } - - cleanup: - (*depth)--; - if (item) - xmlrpc_DECREF(item); - if (env->fault_occurred) { - if (array) - xmlrpc_DECREF(array); - return NULL; - } - return array; -} - - - -/*========================================================================= -** convert_struct -**========================================================================= -** Convert an XML element representing a struct into an xmlrpc_value. -*/ - -static xmlrpc_value * -convert_struct(xmlrpc_env *env, unsigned *depth, xml_element *elem) -{ - xmlrpc_value *strct, *key, *value; - xml_element **members, *member, *name_elem, *value_elem; - size_t size, i; - char *cdata; - size_t cdata_size; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(elem != NULL); - - /* Set up our error-handling preconditions. */ - key = value = NULL; - (*depth)++; - - /* Allocate an array to hold our members. */ - strct = xmlrpc_struct_new(env); - XMLRPC_FAIL_IF_FAULT(env); - - /* Iterate over our children, extracting key/value pairs. */ - /* We don't need to check our element name--our callers do that. */ - members = xml_element_children(elem); - size = xml_element_children_size(elem); - for (i = 0; i < size; i++) { - member = members[i]; - CHECK_NAME(env, member, "member"); - CHECK_CHILD_COUNT(env, member, 2); - - /* Get our key. */ - name_elem = get_child_by_name(env, member, "name"); - XMLRPC_FAIL_IF_FAULT(env); - CHECK_CHILD_COUNT(env, name_elem, 0); - cdata = xml_element_cdata(name_elem); - cdata_size = xml_element_cdata_size(name_elem); - key = make_string(env, cdata, cdata_size); - XMLRPC_FAIL_IF_FAULT(env); - - /* Get our value. */ - value_elem = get_child_by_name(env, member, "value"); - XMLRPC_FAIL_IF_FAULT(env); - value = convert_value(env, depth, value_elem); - XMLRPC_FAIL_IF_FAULT(env); - - /* Add the key/value pair to our struct. */ - xmlrpc_struct_set_value_v(env, strct, key, value); - XMLRPC_FAIL_IF_FAULT(env); - - /* Release our references & memory, and restore our invariants. */ - xmlrpc_DECREF(key); - key = NULL; - xmlrpc_DECREF(value); - value = NULL; - } - - cleanup: - (*depth)--; - if (key) - xmlrpc_DECREF(key); - if (value) - xmlrpc_DECREF(value); - if (env->fault_occurred) { - if (strct) - xmlrpc_DECREF(strct); - return NULL; - } - return strct; -} - - - -/*========================================================================= -** convert_params -**========================================================================= -** Convert an XML element representing a list of params into an -** xmlrpc_value (of type array). -*/ - -static xmlrpc_value * -convert_params(xmlrpc_env *env, unsigned *depth, xml_element *elem) -{ - xmlrpc_value *array, *item; - size_t size, i; - xml_element **params, *param, *value; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(elem != NULL); - - /* Set up our error-handling preconditions. */ - item = NULL; - - /* Allocate an array to hold our parameters. */ - array = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - - /* We're responsible for checking our own element name. */ - CHECK_NAME(env, elem, "params"); - - /* Iterate over our children. */ - size = xml_element_children_size(elem); - params = xml_element_children(elem); - for (i = 0; i < size; i++) { - param = params[i]; - CHECK_NAME(env, param, "param"); - CHECK_CHILD_COUNT(env, param, 1); - - value = xml_element_children(param)[0]; - item = convert_value(env, depth, value); - XMLRPC_FAIL_IF_FAULT(env); - - xmlrpc_array_append_item(env, array, item); - xmlrpc_DECREF(item); - item = NULL; - XMLRPC_FAIL_IF_FAULT(env); - } - - cleanup: - if (env->fault_occurred) { - if (array) - xmlrpc_DECREF(array); - if (item) - xmlrpc_DECREF(item); - return NULL; - } - return array; -} - - - -static void -parseCallXml(xmlrpc_env * const envP, - const char * const xmlData, - size_t const xmlLen, - xml_element ** const callElemP) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - *callElemP = xml_parse(&env, xmlData, (int)xmlLen); - if (env.fault_occurred) - xmlrpc_env_set_fault_formatted( - envP, env.fault_code, "Call is not valid XML. %s", - env.fault_string); - xmlrpc_env_clean(&env); -} - - - -/*========================================================================= -** xmlrpc_parse_call -**========================================================================= -** Given some XML text, attempt to parse it as an XML-RPC call. Return -** a newly allocated xmlrpc_call structure (or NULL, if an error occurs). -** The two output variables will contain either valid values (which -** must free() and xmlrpc_DECREF(), respectively) or NULLs (if an error -** occurs). -*/ - -void -xmlrpc_parse_call(xmlrpc_env * const envP, - const char * const xml_data, - size_t const xml_len, - const char ** const out_method_nameP, - xmlrpc_value ** const out_param_arrayPP) { - - xml_element *call_elem, *name_elem, *params_elem; - char *cdata; - unsigned depth; - size_t call_child_count; - char * outMethodName; - xmlrpc_value * outParamArrayP; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(xml_data != NULL); - XMLRPC_ASSERT(out_method_nameP != NULL && out_param_arrayPP != NULL); - - /* Set up our error-handling preconditions. */ - outMethodName = NULL; - outParamArrayP = NULL; - call_elem = NULL; - - /* SECURITY: Last-ditch attempt to make sure our content length is legal. - ** XXX - This check occurs too late to prevent an attacker from creating - ** an enormous memory block in RAM, so you should try to enforce it - ** *before* reading any data off the network. */ - if (xml_len > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - XMLRPC_FAIL(envP, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large"); - - parseCallXml(envP, xml_data, xml_len, &call_elem); - XMLRPC_FAIL_IF_FAULT(envP); - - /* Pick apart and verify our structure. */ - CHECK_NAME(envP, call_elem, "methodCall"); - call_child_count = xml_element_children_size(call_elem); - if (call_child_count != 2 && call_child_count != 1) - XMLRPC_FAIL1(envP, XMLRPC_PARSE_ERROR, - "Expected to have 1 or 2 children, found %d", - call_child_count); - - /* Extract the method name. - ** SECURITY: We make sure the method name is valid UTF-8. */ - name_elem = get_child_by_name(envP, call_elem, "methodName"); - XMLRPC_FAIL_IF_FAULT(envP); - CHECK_CHILD_COUNT(envP, name_elem, 0); - cdata = xml_element_cdata(name_elem); -#ifdef HAVE_UNICODE_WCHAR - xmlrpc_validate_utf8(envP, cdata, strlen(cdata)); - XMLRPC_FAIL_IF_FAULT(envP); -#endif /* HAVE_UNICODE_WCHAR */ - outMethodName = malloc(strlen(cdata) + 1); - XMLRPC_FAIL_IF_NULL(outMethodName, envP, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for method name"); - strcpy(outMethodName, cdata); - - /* Convert our parameters. */ - if (call_child_count == 1) { - /* Workaround for Ruby XML-RPC and old versions of xmlrpc-epi. */ - outParamArrayP = xmlrpc_build_value(envP, "()"); - XMLRPC_FAIL_IF_FAULT(envP); - } else { - params_elem = get_child_by_name(envP, call_elem, "params"); - XMLRPC_FAIL_IF_FAULT(envP); - depth = 0; - outParamArrayP = convert_params(envP, &depth, params_elem); - XMLRPC_ASSERT(depth == 0); - XMLRPC_FAIL_IF_FAULT(envP); - } - -cleanup: - if (call_elem) - xml_element_free(call_elem); - if (envP->fault_occurred) { - if (outMethodName) - free(outMethodName); - if (outParamArrayP) - xmlrpc_DECREF(outParamArrayP); - outMethodName = NULL; - outParamArrayP = NULL; - } - *out_method_nameP = outMethodName; - *out_param_arrayPP = outParamArrayP; -} - - - -/*========================================================================= -** xmlrpc_parse_response -**========================================================================= -** Given some XML text, attempt to parse it as an XML-RPC response. -** If the response is a regular, valid response, return a new reference -** to the appropriate value. If the response is a fault, or an error -** occurs during processing, return NULL and set up env appropriately. -*/ - -xmlrpc_value * -xmlrpc_parse_response(xmlrpc_env *env, - const char *xml_data, - size_t xml_len) { - - xml_element *response, *child, *value; - unsigned depth; - xmlrpc_value *params, *retval, *fault; - int retval_incremented; - - xmlrpc_value *fault_code_value, *fault_str_value; - xmlrpc_int32 fault_code; - char *fault_str; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(xml_data != NULL); - - /* Set up our error-handling preconditions. */ - response = NULL; - params = fault = NULL; - retval_incremented = 0; - - /* SECURITY: Last-ditch attempt to make sure our content length is legal. - ** XXX - This check occurs too late to prevent an attacker from creating - ** an enormous memory block in RAM, so you should try to enforce it - ** *before* reading any data off the network. */ - if (xml_len > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - XMLRPC_FAIL(env, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC response too large"); - - /* SECURITY: Set up our recursion depth counter. */ - depth = 0; - - /* Parse our XML data. */ - response = xml_parse(env, xml_data, (int)xml_len); - XMLRPC_FAIL_IF_FAULT(env); - - /* Pick apart and verify our structure. */ - CHECK_NAME(env, response, "methodResponse"); - CHECK_CHILD_COUNT(env, response, 1); - child = xml_element_children(response)[0]; - - /* Parse the response itself. */ - if (strcmp("params", xml_element_name(child)) == 0) { - - /* Convert our parameter list. */ - params = convert_params(env, &depth, child); - XMLRPC_FAIL_IF_FAULT(env); - - /* Extract the return value, and jiggle our reference counts. */ - xmlrpc_parse_value(env, params, "(V)", &retval); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_INCREF(retval); - retval_incremented = 1; - - } else if (strcmp("fault", xml_element_name(child)) == 0) { - - /* Convert our fault structure. */ - CHECK_CHILD_COUNT(env, child, 1); - value = xml_element_children(child)[0]; - fault = convert_value(env, &depth, value); - XMLRPC_FAIL_IF_FAULT(env); - XMLRPC_TYPE_CHECK(env, fault, XMLRPC_TYPE_STRUCT); - - /* Get our fault code. */ - fault_code_value = xmlrpc_struct_get_value(env, fault, "faultCode"); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_parse_value(env, fault_code_value, "i", &fault_code); - XMLRPC_FAIL_IF_FAULT(env); - - /* Get our fault string. */ - fault_str_value = xmlrpc_struct_get_value(env, fault, "faultString"); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_parse_value(env, fault_str_value, "s", &fault_str); - XMLRPC_FAIL_IF_FAULT(env); - - /* Return our fault. */ - XMLRPC_FAIL(env, fault_code, fault_str); - - } else { - XMLRPC_FAIL(env, XMLRPC_PARSE_ERROR, - "Expected or in "); - } - - /* Sanity-check our depth-counting code. */ - XMLRPC_ASSERT(depth == 0); - -cleanup: - if (response) - xml_element_free(response); - if (params) - xmlrpc_DECREF(params); - if (fault) - xmlrpc_DECREF(fault); - - if (env->fault_occurred) { - if (retval_incremented) - xmlrpc_DECREF(retval); - return NULL; - } - return retval; -} diff --git a/Utilities/cmxmlrpc/xmlrpc_pthreads.h b/Utilities/cmxmlrpc/xmlrpc_pthreads.h deleted file mode 100644 index 31d4049a1b..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_pthreads.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifndef xmlrpc_pthreads_h_ -#define xmlrpc_pthreads_h_ - -#if !defined(HAVE_PTHREADS) -# error This system does not have PThreads -#endif - -#ifndef WIN32 -# define _REENTRANT -# include -#elif defined (WIN32) -/*typedef PVOID HANDLE; */ -typedef HANDLE pthread_t; -typedef CRITICAL_SECTION pthread_mutex_t; - -#define PTHREAD_MUTEX_INITIALIZER NULL -//usage: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -typedef -struct -{ - int attrs; //currently unused. placeholder. -} pthread_attr_t; - -typedef -struct -{ - int attrs; //currently unused. placeholder. -} pthread_mutexattr_t; - -//typedef void * (*pthread_func)(void *); -typedef unsigned ( __stdcall *pthread_func )( void * ); - -extern int pthread_create(pthread_t *new_thread_ID, - const pthread_attr_t *attr, - pthread_func start_func, void *arg); -extern int pthread_cancel(pthread_t target_thread); -extern int pthread_join(pthread_t target_thread, void **status); -extern int pthread_detach(pthread_t target_thread); - -extern int pthread_mutex_init(pthread_mutex_t *mp, - const pthread_mutexattr_t *attr); -extern int pthread_mutex_lock(pthread_mutex_t *mp); -extern int pthread_mutex_unlock(pthread_mutex_t *mp); -extern int pthread_mutex_destroy(pthread_mutex_t *mp); - -#endif - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_registry.c b/Utilities/cmxmlrpc/xmlrpc_registry.c deleted file mode 100644 index ae3b21cd62..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_registry.c +++ /dev/null @@ -1,819 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** Copyright (C) 2001 by Eric Kidd. All rights reserved. -** Copyright (C) 2001 by Luke Howard. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_server.h" -#include "xmlrpc_int.h" - -/*========================================================================= -** XML-RPC Server Method Registry -**========================================================================= -** A method registry maintains a list of functions, and handles -** dispatching. To build an XML-RPC server, just add a communications -** protocol. :-) -*/ - -static void -install_system_methods (xmlrpc_env *env, xmlrpc_registry *registry); - -xmlrpc_registry * -xmlrpc_registry_new(xmlrpc_env *env) { - - xmlrpc_value *methods; - xmlrpc_registry *registry; - int registry_valid; - - XMLRPC_ASSERT_ENV_OK(env); - - /* Error-handling preconditions. */ - registry = NULL; - registry_valid = 0; - - /* Allocate our memory. */ - methods = xmlrpc_struct_new(env); - XMLRPC_FAIL_IF_FAULT(env); - registry = (xmlrpc_registry*) malloc(sizeof(xmlrpc_registry)); - XMLRPC_FAIL_IF_NULL(registry, env, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for registry"); - - /* Set everything up. */ - registry->_introspection_enabled = 1; - registry->_methods = methods; - registry->_default_method = NULL; - registry->_preinvoke_method = NULL; - registry_valid = 1; - - /* Install our system methods. */ - install_system_methods(env, registry); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (env->fault_occurred) { - if (registry_valid) { - xmlrpc_registry_free(registry); - } else { - if (methods) - xmlrpc_DECREF(methods); - if (registry) - free(registry); - } - return NULL; - } - return registry; -} - - - -void -xmlrpc_registry_free(xmlrpc_registry * registry) { - - XMLRPC_ASSERT_PTR_OK(registry); - XMLRPC_ASSERT(registry->_methods != XMLRPC_BAD_POINTER); - - xmlrpc_DECREF(registry->_methods); - registry->_methods = XMLRPC_BAD_POINTER; - if (registry->_default_method != NULL) - xmlrpc_DECREF(registry->_default_method); - if (registry->_preinvoke_method != NULL) - xmlrpc_DECREF(registry->_preinvoke_method); - free(registry); -} - - - -/*========================================================================= -** xmlrpc_registry_disable_introspection -**========================================================================= -** See xmlrpc.h for more documentation. -*/ - -void -xmlrpc_registry_disable_introspection(xmlrpc_registry * registry) { - XMLRPC_ASSERT_PTR_OK(registry); - registry->_introspection_enabled = 0; -} - - - -/*========================================================================= -** xmlrpc_registry_add_method -**========================================================================= -** See xmlrpc.h for more documentation. -*/ - -void -xmlrpc_registry_add_method(xmlrpc_env *env, - xmlrpc_registry *registry, - const char *host, - const char *method_name, - xmlrpc_method method, - void *user_data) { - - xmlrpc_registry_add_method_w_doc (env, registry, host, method_name, - method, user_data, "?", - "No help is available for this method."); -} - - - -void -xmlrpc_registry_add_method_w_doc(xmlrpc_env *env, - xmlrpc_registry *registry, - const char *host, - const char *method_name, - xmlrpc_method method, - void *user_data, - const char *signature, - const char *help) { - xmlrpc_value *method_info; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(registry); - XMLRPC_ASSERT(host == NULL); - XMLRPC_ASSERT_PTR_OK(method_name); - XMLRPC_ASSERT_PTR_OK(method); - - /* Store our method and user data into our hash table. */ - method_info = xmlrpc_build_value(env, "(ppss)", (void*) method, user_data, - signature, help); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_struct_set_value(env, registry->_methods, method_name, method_info); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (method_info) - xmlrpc_DECREF(method_info); - -} - - - -/*========================================================================= -** xmlrpc_registry_set_default_method -**========================================================================= -** See xmlrpc.h for more documentation. -*/ - -void -xmlrpc_registry_set_default_method(xmlrpc_env *env, - xmlrpc_registry *registry, - xmlrpc_default_method handler, - void *user_data) { - xmlrpc_value *method_info; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(registry); - XMLRPC_ASSERT_PTR_OK(handler); - - /* Store our method and user data into our hash table. */ - method_info = xmlrpc_build_value(env, "(pp)", (void*) handler, user_data); - XMLRPC_FAIL_IF_FAULT(env); - - /* Dispose of any pre-existing default method and install ours. */ - if (registry->_default_method) - xmlrpc_DECREF(registry->_default_method); - registry->_default_method = method_info; - -cleanup: - if (env->fault_occurred) { - if (method_info) - xmlrpc_DECREF(method_info); - } -} - - - -/*========================================================================= -** xmlrpc_registry_set_preinvoke_method -**========================================================================= -** See xmlrpc.h for more documentation. -*/ - -void -xmlrpc_registry_set_preinvoke_method(xmlrpc_env *env, - xmlrpc_registry *registry, - xmlrpc_preinvoke_method handler, - void *user_data) { - xmlrpc_value *method_info; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(registry); - XMLRPC_ASSERT_PTR_OK(handler); - - /* Store our method and user data into our hash table. */ - method_info = xmlrpc_build_value(env, "(pp)", (void*) handler, user_data); - XMLRPC_FAIL_IF_FAULT(env); - - /* Dispose of any pre-existing preinvoke method and install ours. */ - if (registry->_preinvoke_method) - xmlrpc_DECREF(registry->_preinvoke_method); - registry->_preinvoke_method = method_info; - - cleanup: - if (env->fault_occurred) { - if (method_info) - xmlrpc_DECREF(method_info); - } -} - - - -/*========================================================================= -** dispatch_call -**========================================================================= -** An internal method which actually does the dispatch. This may get -** prettified and exported at some point in the future. -*/ - -static void -callPreinvokeMethodIfAny(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_value * const paramArrayP) { - - /* Get the preinvoke method, if it is set. */ - if (registryP->_preinvoke_method) { - xmlrpc_preinvoke_method preinvoke_method; - void * user_data; - - xmlrpc_parse_value(envP, registryP->_preinvoke_method, "(pp)", - &preinvoke_method, &user_data); - if (!envP->fault_occurred) - (*preinvoke_method)(envP, methodName, - paramArrayP, user_data); - } -} - - - -static void -callDefaultMethod(xmlrpc_env * const envP, - xmlrpc_value * const defaultMethodInfo, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - xmlrpc_default_method default_method; - void * user_data; - - xmlrpc_parse_value(envP, defaultMethodInfo, "(pp)", - &default_method, &user_data); - - if (!envP->fault_occurred) - *resultPP = (*default_method)(envP, NULL, methodName, - paramArrayP, user_data); -} - - - -static void -callNamedMethod(xmlrpc_env * const envP, - xmlrpc_value * const methodInfo, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - xmlrpc_method method; - void * user_data; - - xmlrpc_parse_value(envP, methodInfo, "(pp*)", &method, &user_data); - if (!envP->fault_occurred) - *resultPP = (*method)(envP, paramArrayP, user_data); -} - - - -static void -dispatch_call(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const methodName, - xmlrpc_value * const paramArrayP, - xmlrpc_value ** const resultPP) { - - callPreinvokeMethodIfAny(envP, registryP, methodName, paramArrayP); - if (!envP->fault_occurred) { - xmlrpc_value * method_info; - - /* Look up the method info for the named method. */ - xmlrpc_struct_find_value(envP, registryP->_methods, - methodName, &method_info); - if (!envP->fault_occurred) { - if (method_info) - callNamedMethod(envP, method_info, paramArrayP, resultPP); - else { - if (registryP->_default_method) - callDefaultMethod(envP, registryP->_default_method, - methodName, paramArrayP, - resultPP); - else { - /* No matching method, and no default. */ - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_NO_SUCH_METHOD_ERROR, - "Method '%s' not defined", methodName); - } - } - } - } - /* For backward compatibility, for sloppy users: */ - if (envP->fault_occurred) - *resultPP = NULL; -} - - - -/*========================================================================= -** xmlrpc_registry_process_call -**========================================================================= -** -*/ - -xmlrpc_mem_block * -xmlrpc_registry_process_call(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host ATTR_UNUSED, - const char * const xml_data, - size_t const xml_len) { - - xmlrpc_mem_block * output; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_PTR_OK(xml_data); - - xmlrpc_traceXml("XML-RPC CALL", xml_data, (unsigned int)xml_len); - - /* Allocate our output buffer. - ** If this fails, we need to die in a special fashion. */ - output = XMLRPC_MEMBLOCK_NEW(char, envP, 0); - if (!envP->fault_occurred) { - const char * methodName; - xmlrpc_value * paramArray; - xmlrpc_env fault; - - xmlrpc_env_init(&fault); - - xmlrpc_parse_call(&fault, xml_data, xml_len, - &methodName, ¶mArray); - - if (!fault.fault_occurred) { - xmlrpc_value * result; - - dispatch_call(&fault, registryP, methodName, paramArray, &result); - - if (!fault.fault_occurred) { - xmlrpc_serialize_response(envP, output, result); - - /* A comment here used to say that - xmlrpc_serialize_response() could fail and "leave - stuff in the buffer." Don't know what that means, - but it sounds like something that needs to be - fixed. The old code aborted the program here if - xmlrpc_serialize_repsonse() failed. 04.11.17 - */ - xmlrpc_DECREF(result); - } - xmlrpc_strfree(methodName); - xmlrpc_DECREF(paramArray); - } - if (!envP->fault_occurred && fault.fault_occurred) - xmlrpc_serialize_fault(envP, output, &fault); - - xmlrpc_env_clean(&fault); - - if (envP->fault_occurred) - XMLRPC_MEMBLOCK_FREE(char, output); - else - xmlrpc_traceXml("XML-RPC RESPONSE", - XMLRPC_MEMBLOCK_CONTENTS(char, output), - (unsigned int)XMLRPC_MEMBLOCK_SIZE(char, output)); - } - return output; -} - - - -/*========================================================================= -** system.multicall -**========================================================================= -** Low-tech support for transparent, boxed methods. -*/ - -static char *multicall_help = -"Process an array of calls, and return an array of results. Calls should " -"be structs of the form {'methodName': string, 'params': array}. Each " -"result will either be a single-item array containg the result value, or " -"a struct of the form {'faultCode': int, 'faultString': string}. This " -"is useful when you need to make lots of small calls without lots of " -"round trips."; - -static xmlrpc_value * -call_one_method(xmlrpc_env *env, xmlrpc_registry *registry, - xmlrpc_value *method_info) { - - xmlrpc_value *result_val, *result; - char *method_name; - xmlrpc_value *param_array; - - /* Error-handling preconditions. */ - result = result_val = NULL; - - /* Extract our method name and parameters. */ - xmlrpc_parse_value(env, method_info, "{s:s,s:A,*}", - "methodName", &method_name, - "params", ¶m_array); - XMLRPC_FAIL_IF_FAULT(env); - - /* Watch out for a deep recursion attack. */ - if (strcmp(method_name, "system.multicall") == 0) - XMLRPC_FAIL(env, XMLRPC_REQUEST_REFUSED_ERROR, - "Recursive system.multicall strictly forbidden"); - - /* Perform the call. */ - dispatch_call(env, registry, method_name, param_array, &result_val); - XMLRPC_FAIL_IF_FAULT(env); - - /* Build our one-item result array. */ - result = xmlrpc_build_value(env, "(V)", result_val); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (result_val) - xmlrpc_DECREF(result_val); - if (env->fault_occurred) { - if (result) - xmlrpc_DECREF(result); - return NULL; - } - return result; -} - - - -static xmlrpc_value * -system_multicall(xmlrpc_env *env, - xmlrpc_value *param_array, - void *user_data) { - - xmlrpc_registry *registry; - xmlrpc_value *methlist, *methinfo, *results, *result; - size_t size, i; - xmlrpc_env env2; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(param_array); - XMLRPC_ASSERT_PTR_OK(user_data); - - /* Error-handling preconditions. */ - results = result = NULL; - xmlrpc_env_init(&env2); - - /* Turn our arguments into something more useful. */ - registry = (xmlrpc_registry*) user_data; - xmlrpc_parse_value(env, param_array, "(A)", &methlist); - XMLRPC_FAIL_IF_FAULT(env); - - /* Create an empty result list. */ - results = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - - /* Loop over our input list, calling each method in turn. */ - size = xmlrpc_array_size(env, methlist); - XMLRPC_ASSERT_ENV_OK(env); - for (i = 0; i < size; i++) { - methinfo = xmlrpc_array_get_item(env, methlist, (int)i); - XMLRPC_ASSERT_ENV_OK(env); - - /* Call our method. */ - xmlrpc_env_clean(&env2); - xmlrpc_env_init(&env2); - result = call_one_method(&env2, registry, methinfo); - - /* Turn any fault into a structure. */ - if (env2.fault_occurred) { - XMLRPC_ASSERT(result == NULL); - result = - xmlrpc_build_value(env, "{s:i,s:s}", - "faultCode", (xmlrpc_int32) env2.fault_code, - "faultString", env2.fault_string); - XMLRPC_FAIL_IF_FAULT(env); - } - - /* Append this method result to our master array. */ - xmlrpc_array_append_item(env, results, result); - xmlrpc_DECREF(result); - result = NULL; - XMLRPC_FAIL_IF_FAULT(env); - } - - cleanup: - xmlrpc_env_clean(&env2); - if (result) - xmlrpc_DECREF(result); - if (env->fault_occurred) { - if (results) - xmlrpc_DECREF(results); - return NULL; - } - return results; -} - - - -/*========================================================================= -** system.listMethods -**========================================================================= -** List all available methods by name. -*/ - -static char *listMethods_help = -"Return an array of all available XML-RPC methods on this server."; - -static xmlrpc_value * -system_listMethods(xmlrpc_env *env, - xmlrpc_value *param_array, - void *user_data) { - - xmlrpc_registry *registry; - xmlrpc_value *method_names, *method_name, *method_info; - size_t size, i; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(param_array); - XMLRPC_ASSERT_PTR_OK(user_data); - - /* Error-handling preconditions. */ - method_names = NULL; - - /* Turn our arguments into something more useful. */ - registry = (xmlrpc_registry*) user_data; - xmlrpc_parse_value(env, param_array, "()"); - XMLRPC_FAIL_IF_FAULT(env); - - /* Make sure we're allowed to introspect. */ - if (!registry->_introspection_enabled) - XMLRPC_FAIL(env, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection disabled for security reasons"); - - /* Iterate over all the methods in the registry, adding their names - ** to a list. */ - method_names = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - size = xmlrpc_struct_size(env, registry->_methods); - XMLRPC_FAIL_IF_FAULT(env); - for (i = 0; i < size; i++) { - xmlrpc_struct_get_key_and_value(env, registry->_methods, (int)i, - &method_name, &method_info); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_array_append_item(env, method_names, method_name); - XMLRPC_FAIL_IF_FAULT(env); - } - - cleanup: - if (env->fault_occurred) { - if (method_names) - xmlrpc_DECREF(method_names); - return NULL; - } - return method_names; -} - - - -/*========================================================================= -** system.methodHelp -**========================================================================= -** Get the help string for a particular method. -*/ - -static char *methodHelp_help = -"Given the name of a method, return a help string."; - -static xmlrpc_value * -system_methodHelp(xmlrpc_env *env, - xmlrpc_value *param_array, - void *user_data) { - - xmlrpc_registry *registry; - char *method_name; - xmlrpc_value *ignored1, *ignored2, *ignored3, *help; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(param_array); - XMLRPC_ASSERT_PTR_OK(user_data); - - /* Turn our arguments into something more useful. */ - registry = (xmlrpc_registry*) user_data; - xmlrpc_parse_value(env, param_array, "(s)", &method_name); - XMLRPC_FAIL_IF_FAULT(env); - - /* Make sure we're allowed to introspect. */ - if (!registry->_introspection_enabled) - XMLRPC_FAIL(env, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection disabled for security reasons"); - - /* Get our documentation string. */ - xmlrpc_parse_value(env, registry->_methods, "{s:(VVVV*),*}", - method_name, &ignored1, &ignored2, &ignored3, &help); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (env->fault_occurred) - return NULL; - xmlrpc_INCREF(help); - return help; -} - - - -/*========================================================================= -** system.methodSignature -**========================================================================= -** Return an array of arrays describing possible signatures for this -** method. -** -** XXX - This is the ugliest function in the entire library. -*/ - -static char *methodSignature_help = -"Given the name of a method, return an array of legal signatures. " -"Each signature is an array of strings. The first item of each signature " -"is the return type, and any others items are parameter types."; - -static char *bad_sig_str = -"Application has incorrect method signature information"; - -#define BAD_SIG(env) \ - XMLRPC_FAIL((env), XMLRPC_INTERNAL_ERROR, bad_sig_str); - -static xmlrpc_value * -system_methodSignature(xmlrpc_env *env, - xmlrpc_value *param_array, - void *user_data) { - - xmlrpc_registry *registry; - char *method_name; - xmlrpc_value *ignored1, *ignored2, *ignored3; - xmlrpc_value *item, *current, *result; - int at_sig_start; - char *sig, *code = 0; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(param_array); - XMLRPC_ASSERT_PTR_OK(user_data); - - /* Error-handling preconditions. */ - item = current = result = NULL; - - /* Turn our arguments into something more useful. */ - registry = (xmlrpc_registry*) user_data; - xmlrpc_parse_value(env, param_array, "(s)", &method_name); - XMLRPC_FAIL_IF_FAULT(env); - - /* Make sure we're allowed to introspect. */ - if (!registry->_introspection_enabled) - XMLRPC_FAIL(env, XMLRPC_INTROSPECTION_DISABLED_ERROR, - "Introspection disabled for security reasons"); - - /* Get our signature string. */ - xmlrpc_parse_value(env, registry->_methods, "{s:(VVsV*),*}", - method_name, &ignored1, &ignored2, &sig, &ignored3); - XMLRPC_FAIL_IF_FAULT(env); - - if (sig[0] == '?' && sig[1] == '\0') { - /* No signature supplied. */ - result = xmlrpc_build_value(env, "s", "undef"); - XMLRPC_FAIL_IF_FAULT(env); - } else { - /* Build an array of arrays. */ - current = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - result = xmlrpc_build_value(env, "(V)", current); - XMLRPC_FAIL_IF_FAULT(env); - at_sig_start = 1; - - do { - next_loop: - - /* Process the current code. */ - switch (*(sig++)) { - case 'i': code = "int"; break; - case 'b': code = "boolean"; break; - case 'd': code = "double"; break; - case 's': code = "string"; break; - case '8': code = "dateTime.iso8601"; break; - case '6': code = "base64"; break; - case 'S': code = "struct"; break; - case 'A': code = "array"; break; - - case ',': - /* Start a new signature array. */ - if (at_sig_start) - BAD_SIG(env); - xmlrpc_DECREF(current); - current = xmlrpc_build_value(env, "()"); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_array_append_item(env, result, current); - XMLRPC_FAIL_IF_FAULT(env); - at_sig_start = 1; - goto next_loop; - - default: - BAD_SIG(env); - } - - /* Append the appropriate string to our current signature. */ - item = xmlrpc_build_value(env, "s", code); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_array_append_item(env, current, item); - xmlrpc_DECREF(item); - item = NULL; - XMLRPC_FAIL_IF_FAULT(env); - - /* Advance to the next code, and skip over ':' if necessary. */ - if (at_sig_start) { - if (*sig != ':') - BAD_SIG(env); - sig++; - at_sig_start = 0; - } - - } while (*sig != '\0'); - } - - cleanup: - if (item) - xmlrpc_DECREF(item); - if (current) - xmlrpc_DECREF(current); - if (env->fault_occurred) { - if (result) - xmlrpc_DECREF(result); - return NULL; - } - return result; -} - - - -/*========================================================================= -** install_system_methods -**========================================================================= -** Install the standard methods under system.*. -** This particular function is highly experimental, and may disappear -** without warning. -*/ - -static void -install_system_methods(xmlrpc_env *env, xmlrpc_registry *registry) { - - xmlrpc_registry_add_method_w_doc(env, registry, NULL, - "system.listMethods", - &system_listMethods, registry, - "A:", listMethods_help); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_registry_add_method_w_doc(env, registry, NULL, - "system.methodSignature", - &system_methodSignature, registry, - "A:s", methodSignature_help); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_registry_add_method_w_doc(env, registry, NULL, - "system.methodHelp", - &system_methodHelp, registry, - "s:s", methodHelp_help); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_registry_add_method_w_doc(env, registry, NULL, - "system.multicall", - &system_multicall, registry, - "A:A", multicall_help); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - return; -} diff --git a/Utilities/cmxmlrpc/xmlrpc_serialize.c b/Utilities/cmxmlrpc/xmlrpc_serialize.c deleted file mode 100644 index 5315ff9168..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_serialize.c +++ /dev/null @@ -1,620 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" - -#define CRLF "\015\012" -#define SMALL_BUFFER_SZ (128) -#define XML_PROLOGUE ""CRLF - - -/*========================================================================= -** format_out -**========================================================================= -** A lightweight print routine for use with various serialization -** functions. Only use this routine for printing small objects--it uses -** a fixed-size internal buffer and returns an error on overflow. -** In particular, do NOT use this routine to print XML-RPC string values! -*/ - -static void -format_out(xmlrpc_env *env, - xmlrpc_mem_block *output, - char *format_string, - ...) { - - va_list args; - char buffer[SMALL_BUFFER_SZ]; - int count; - - XMLRPC_ASSERT_ENV_OK(env); - - va_start(args, format_string); - - /* We assume that this function is present and works correctly. Right. */ - count = vsnprintf(buffer, SMALL_BUFFER_SZ, format_string, args); - - /* Old C libraries return -1 if vsnprintf overflows its buffer. - ** New C libraries return the number of characters which *would* have - ** been printed if the error did not occur. This is impressively vile. - ** Thank the C99 committee for this bright idea. But wait! We also - ** need to keep track of the trailing NULL. */ - if (count < 0 || count >= (SMALL_BUFFER_SZ - 1)) - XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, - "format_out overflowed internal buffer"); - - /* Append our new data to our output. */ - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, buffer, count); - XMLRPC_FAIL_IF_FAULT(env); - -cleanup: - va_end(args); -} - - -/*========================================================================= -** Warnings About Invalid UTF-8 -**========================================================================= -** We claim to send UTF-8 data to the network. But we rely on application -** programs to pass us correctly-formed UTF-8 data, which is very naive -** and optimistic. -** -** In debudding mode, we call this routine to issue dire-sounding -** warnings. For the sake of safety, this routine never exits the -** program or does anything else drastic. -** -** This routine almost certainly slows down our output. -*/ - -#if !defined NDEBUG && defined HAVE_UNICODE_WCHAR - -static void -sanity_check_utf8(const char * const str, - size_t const len) { - - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_validate_utf8(&env, str, len); - if (env.fault_occurred) - fprintf(stderr, "*** xmlrpc-c WARNING ***: %s (%s)\n", - "Application sending corrupted UTF-8 data to network", - env.fault_string); - xmlrpc_env_clean(&env); -} -#endif - - - -/*========================================================================= -** Escaping Strings -**========================================================================= -*/ - -static xmlrpc_mem_block * -escape_string(xmlrpc_env * const env, - const char * const str, - size_t const len) { - - xmlrpc_mem_block *retval; - size_t i, needed; - char *out; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(str != NULL); - - /* Sanity-check this string before we print it. */ -#if !defined NDEBUG && defined HAVE_UNICODE_WCHAR - sanity_check_utf8(str, len); -#endif - - /* Calculate the amount of space we'll need. */ - needed = 0; - for (i = 0; i < len; i++) { - if (str[i] == '<') - needed += 4; /* < */ - else if (str[i] == '>') - needed += 4; /* > */ - else if (str[i] == '&') - needed += 5; /* & */ - else - needed++; - } - - /* Allocate our memory block. */ - retval = XMLRPC_TYPED_MEM_BLOCK_NEW(char, env, needed); - XMLRPC_FAIL_IF_FAULT(env); - - /* Copy over the newly-allocated data. */ - out = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, retval); - for (i = 0; i < len; i++) { - if (str[i] == '<') { - *out++ = '&'; - *out++ = 'l'; - *out++ = 't'; - *out++ = ';'; - } else if (str[i] == '>') { - *out++ = '&'; - *out++ = 'g'; - *out++ = 't'; - *out++ = ';'; - } else if (str[i] == '&') { - *out++ = '&'; - *out++ = 'a'; - *out++ = 'm'; - *out++ = 'p'; - *out++ = ';'; - } else { - *out++ = str[i]; - } - } - - cleanup: - if (env->fault_occurred) { - if (retval) - XMLRPC_TYPED_MEM_BLOCK_FREE(char, retval); - retval = NULL; - } - return retval; -} - - - -static xmlrpc_mem_block* -escape_block (xmlrpc_env *env, - xmlrpc_mem_block *block) { - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(block != NULL); - - return escape_string(env, - XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, block), - XMLRPC_TYPED_MEM_BLOCK_SIZE(char, block)); -} - - - -/*========================================================================= -** xmlrpc_serialize_string_data -**========================================================================= -** Escape and print the contents of a string. -*/ - -static void -xmlrpc_serialize_string_data(xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_value *string) { - - xmlrpc_mem_block *escaped; - char *contents; - size_t size; - - /* Since this routine can only be called internally, we only need - ** an assertion here, not a runtime type check. - ** XXX - Temporarily disabled because we're using this code to - ** print values as well. */ - /* XMLRPC_ASSERT(string->_type == XMLRPC_TYPE_STRING); */ - - /* Escape any '&' and '<' characters in the string. */ - escaped = escape_block(env, &string->_block); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, escaped); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, escaped) - 1; - - /* Print the string. */ - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, contents, size); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (escaped) - XMLRPC_TYPED_MEM_BLOCK_FREE(char, escaped); -} - - - -/*========================================================================= -** xmlrpc_serialize_base64_data -**========================================================================= -** Print the contents of a memory block as well-formed Base64 data. -*/ - -static void -xmlrpc_serialize_base64_data (xmlrpc_env *env, - xmlrpc_mem_block *output, - unsigned char* data, size_t len) { - - xmlrpc_mem_block *encoded; - unsigned char *contents; - size_t size; - - /* Encode the data. */ - encoded = xmlrpc_base64_encode_without_newlines(env, data, len); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char, encoded); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(unsigned char, encoded); - - /* Print the data. */ - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, contents, size); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (encoded) - XMLRPC_TYPED_MEM_BLOCK_FREE(char, encoded); -} - - - -/*========================================================================= -** xmlrpc_serialize_struct -**========================================================================= -** Dump the contents of a struct. -*/ - -static void -xmlrpc_serialize_struct(xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_value *strct) { - - size_t size; - size_t i; - xmlrpc_value *key, *value; - - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - size = xmlrpc_struct_size(env, strct); - XMLRPC_FAIL_IF_FAULT(env); - for (i = 0; i < size; i++) { - xmlrpc_struct_get_key_and_value(env, strct, (int)i, &key, &value); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_string_data(env, output, key); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_value(env, output, value); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - } - - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - -cleanup: - return; -} - - - -/*========================================================================= -** xmlrpc_serialize_value -**========================================================================= -** Dump a value in the appropriate fashion. -*/ - -void -xmlrpc_serialize_value(xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_value *value) { - - xmlrpc_value *item; - size_t size; - unsigned char* contents; - size_t i; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(output != NULL); - XMLRPC_ASSERT_VALUE_OK(value); - - /* Print our ubiquitous header. */ - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - - switch (value->_type) { - - case XMLRPC_TYPE_INT: - /* XXX - We assume that '%i' is the appropriate format specifier - ** for an xmlrpc_int32 value. We should add some test cases to - ** make sure this works. */ - format_out(env, output, "%i", value->_value.i); - break; - - case XMLRPC_TYPE_BOOL: - /* XXX - We assume that '%i' is the appropriate format specifier - ** for an xmlrpc_bool value. */ - format_out(env, output, "%i", - (value->_value.b) ? 1 : 0); - break; - - case XMLRPC_TYPE_DOUBLE: - /* We must output a number of the form [+-]?\d*.\d*. */ - format_out(env, output, "%.17g", value->_value.d); - break; - - case XMLRPC_TYPE_STRING: - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_string_data(env, output, value); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""); - break; - - case XMLRPC_TYPE_ARRAY: - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - /* Serialize each item. */ - size = xmlrpc_array_size(env, value); - XMLRPC_FAIL_IF_FAULT(env); - for (i = 0; i < size; i++) { - item = xmlrpc_array_get_item(env, value, (int)i); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_value(env, output, item); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, CRLF); - XMLRPC_FAIL_IF_FAULT(env); - } - - format_out(env, output, ""); - break; - - case XMLRPC_TYPE_STRUCT: - xmlrpc_serialize_struct(env, output, value); - break; - - case XMLRPC_TYPE_BASE64: - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(unsigned char, - &value->_block); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(unsigned char, &value->_block); - xmlrpc_serialize_base64_data(env, output, contents, size); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""); - break; - - case XMLRPC_TYPE_DATETIME: - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_string_data(env, output, value); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""); - break; - - case XMLRPC_TYPE_C_PTR: - xmlrpc_env_set_fault_formatted( - env, XMLRPC_INTERNAL_ERROR, - "Tried to serialize a C pointer value."); - break; - - case XMLRPC_TYPE_DEAD: - xmlrpc_env_set_fault_formatted( - env, XMLRPC_INTERNAL_ERROR, - "Tried to serialize a deaad value."); - break; - - default: - xmlrpc_env_set_fault_formatted( - env, XMLRPC_INTERNAL_ERROR, - "Invalid xmlrpc_value type: %d", value->_type); - } - XMLRPC_FAIL_IF_FAULT(env); - - /* Print our ubiquitous footer. */ - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - return; -} - - - -/*========================================================================= -** xmlrpc_serialize_params -**========================================================================= -** Serialize a list as a set of parameters. -*/ - -void -xmlrpc_serialize_params(xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_value *param_array) { - - size_t size, i; - xmlrpc_value *item; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(output != NULL); - XMLRPC_ASSERT_VALUE_OK(param_array); - - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - /* Dump each parameter. */ - size = xmlrpc_array_size(env, param_array); - XMLRPC_FAIL_IF_FAULT(env); - for (i = 0; i < size; i++) { - format_out(env, output, ""); - XMLRPC_FAIL_IF_FAULT(env); - item = xmlrpc_array_get_item(env, param_array, (int)i); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_value(env, output, item); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - } - - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - return; -} - - - -/*========================================================================= -** xmlrpc_serialize_call -**========================================================================= -** Serialize an XML-RPC call. -*/ - -void -xmlrpc_serialize_call(xmlrpc_env * const env, - xmlrpc_mem_block * const output, - const char * const method_name, - xmlrpc_value * const param_array) { - - xmlrpc_mem_block *escaped; - char *contents; - size_t size; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(output != NULL); - XMLRPC_ASSERT(method_name != NULL); - XMLRPC_ASSERT_VALUE_OK(param_array); - - /* Set up our error-handling preconditions. */ - escaped = NULL; - - /* Dump our header. */ - format_out(env, output, XML_PROLOGUE); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF""); - XMLRPC_FAIL_IF_FAULT(env); - - /* Dump the method name. */ - escaped = escape_string(env, method_name, strlen(method_name)); - XMLRPC_FAIL_IF_FAULT(env); - contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, escaped); - size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, escaped); - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, env, output, contents, size); - XMLRPC_FAIL_IF_FAULT(env); - - /* Dump our parameters and footer. */ - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - xmlrpc_serialize_params(env, output, param_array); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (escaped) - xmlrpc_mem_block_free(escaped); -} - - - -/*========================================================================= -** xmlrpc_serialize_response -**========================================================================= -** Serialize the (non-fault) response to an XML-RPC call. -*/ - -void -xmlrpc_serialize_response (xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_value *value) { - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(output != NULL); - XMLRPC_ASSERT_VALUE_OK(value); - - format_out(env, output, XML_PROLOGUE); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF""CRLF""); - XMLRPC_FAIL_IF_FAULT(env); - - xmlrpc_serialize_value(env, output, value); - XMLRPC_FAIL_IF_FAULT(env); - - format_out(env, output, - ""CRLF""CRLF""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - return; -} - - - -/*========================================================================= -** xmlrpc_serialize_fault -**========================================================================= -** Serialize an XML-RPC fault. -** -** If this function fails, it will set up the first env argument. You'll -** need to take some other drastic action to produce a serialized fault -** of your own. (This function should only fail in an out-of-memory -** situation, AFAIK.) -*/ - -void -xmlrpc_serialize_fault(xmlrpc_env *env, - xmlrpc_mem_block *output, - xmlrpc_env *fault) { - - xmlrpc_value *strct; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(output != NULL); - XMLRPC_ASSERT(fault != NULL && fault->fault_occurred); - - /* Build a fault structure. */ - strct = xmlrpc_build_value(env, "{s:i,s:s}", - "faultCode", (xmlrpc_int32) fault->fault_code, - "faultString", fault->fault_string); - XMLRPC_FAIL_IF_FAULT(env); - - /* Output our header. */ - format_out(env, output, XML_PROLOGUE); - XMLRPC_FAIL_IF_FAULT(env); - format_out(env, output, ""CRLF""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - /* Serialize our fault structure. */ - xmlrpc_serialize_value(env, output, strct); - XMLRPC_FAIL_IF_FAULT(env); - - /* Output our footer. */ - format_out(env, output, CRLF""CRLF""CRLF); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (strct) - xmlrpc_DECREF(strct); -} diff --git a/Utilities/cmxmlrpc/xmlrpc_server.h b/Utilities/cmxmlrpc/xmlrpc_server.h deleted file mode 100644 index 7024f43e8e..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_server.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#ifndef _XMLRPC_SERVER_H_ -#define _XMLRPC_SERVER_H_ 1 - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*========================================================================= -** XML-RPC Server Method Registry -**========================================================================= -** A method registry maintains a list of functions, and handles -** dispatching. To build an XML-RPC server, just add an XML-RPC protocol -** driver. -** -** Methods are C functions which take some combination of the following -** parameters. All pointers except user_data belong to the library, and -** must not be freed by the callback or used after the callback returns. -** -** env: An XML-RPC error-handling environment. No faults will be -** set when the function is called. If an error occurs, -** set an appropriate fault and return NULL. (If a fault is -** set, the NULL return value will be enforced!) -** host: The 'Host:' header passed by the XML-RPC client, or NULL, -** if no 'Host:' header has been provided. -** method_name: The name used to call this method. -** user_data: The user_data used to register this method. -** param_array: The parameters passed to this function, stored in an -** XML-RPC array. You are *not* responsible for calling -** xmlrpc_DECREF on this array. -** -** Return value: If no fault has been set, the function must return a -** valid xmlrpc_value. This will be serialized, returned -** to the caller, and xmlrpc_DECREF'd. -*/ - -/* A function to call before invoking a method for doing things like access -** control or sanity checks. If a fault is set from this function, the -** method will not be called and the fault will be returned. */ -typedef void -(*xmlrpc_preinvoke_method)(xmlrpc_env * env, - const char * method_name, - xmlrpc_value * param_array, - void * user_data); - -/* An ordinary method. */ -typedef xmlrpc_value * -(*xmlrpc_method)(xmlrpc_env * env, - xmlrpc_value * param_array, - void * user_data); - -/* A default method to call if no method can be found. */ -typedef xmlrpc_value * -(*xmlrpc_default_method)(xmlrpc_env * env, - const char * host, - const char * method_name, - xmlrpc_value * param_array, - void * user_data); - -/* Our registry structure. This has no public members. */ -typedef struct _xmlrpc_registry xmlrpc_registry; - -/* Create a new method registry. */ -xmlrpc_registry * -xmlrpc_registry_new(xmlrpc_env * env); - -/* Delete a method registry. */ -void -xmlrpc_registry_free(xmlrpc_registry * registry); - -/* Disable introspection. The xmlrpc_registry has introspection -** capability built-in. If you want to make nosy people work harder, -** you can turn this off. */ -void -xmlrpc_registry_disable_introspection(xmlrpc_registry * registry); - -/* Register a method. The host parameter must be NULL (for now). You -** are responsible for owning and managing user_data. The registry -** will make internal copies of any other pointers it needs to -** keep around. */ -void -xmlrpc_registry_add_method(xmlrpc_env * env, - xmlrpc_registry * registry, - const char * host, - const char * method_name, - xmlrpc_method method, - void * user_data); - -/* As above, but allow the user to supply introspection information. -** -** Signatures use their own little description language. It consists -** of one-letter type code (similar to the ones used in xmlrpc_parse_value) -** for the result, a colon, and zero or more one-letter type codes for -** the parameters. For example: -** i:ibdsAS86 -** If a function has more than one possible prototype, separate them with -** commas: -** i:,i:s,i:ii -** If the function signature can't be represented using this language, -** pass a single question mark: -** ? -** Help strings are ASCII text, and may contain HTML markup. */ -void -xmlrpc_registry_add_method_w_doc(xmlrpc_env * env, - xmlrpc_registry * registry, - const char * host, - const char * method_name, - xmlrpc_method method, - void * user_data, - const char * signature, - const char * help); - -/* Given a registry, a host name, and XML data; parse the , -** find the appropriate method, call it, serialize the response, and -** return it as an xmlrpc_mem_block. Most errors will be serialized -** as responses. If a *really* bad error occurs, set a fault and -** return NULL. (Actually, we currently give up with a fatal error, -** but that should change eventually.) -** The caller is responsible for destroying the memory block. */ -xmlrpc_mem_block * -xmlrpc_registry_process_call(xmlrpc_env * const envP, - xmlrpc_registry * const registryP, - const char * const host, - const char * const xml_data, - size_t const xml_len); - -/* Define a default method for the specified registry. This will be invoked -** if no other method matches. The user_data pointer is property of the -** application, and will not be freed or manipulated by the registry. */ -void -xmlrpc_registry_set_default_method(xmlrpc_env * env, - xmlrpc_registry * registry, - xmlrpc_default_method handler, - void * user_data); - -/* Define a preinvoke method for the specified registry. This function will -** be called before any method (either the default or a registered one) is -** invoked. Applications can use this to do things like access control or -** sanity checks. The user_data pointer is property of the application, -** and will not be freed or manipulated by the registry. */ -void -xmlrpc_registry_set_preinvoke_method(xmlrpc_env * env, - xmlrpc_registry * registry, - xmlrpc_preinvoke_method method, - void * user_data); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_server_abyss.c b/Utilities/cmxmlrpc/xmlrpc_server_abyss.c deleted file mode 100644 index 5964c33c0a..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_server_abyss.c +++ /dev/null @@ -1,799 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -** There is more copyright information in the bottom half of this file. -** Please see it for more details. */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "abyss.h" - -#include "xmlrpc.h" -#include "xmlrpc_server.h" -#include "xmlrpc_int.h" -#include "xmlrpc_server_abyss.h" -#include "xmlrpc_server_abyss_int.h" - - -/*========================================================================= -** die_if_fault_occurred -**========================================================================= -** If certain kinds of out-of-memory errors occur during server setup, -** we want to quit and print an error. -*/ - -static void die_if_fault_occurred(xmlrpc_env *env) { - if (env->fault_occurred) { - fprintf(stderr, "Unexpected XML-RPC fault: %s (%d)\n", - env->fault_string, env->fault_code); - exit(1); - } -} - - - -/*========================================================================= -** send_xml_data -**========================================================================= -** Blast some XML data back to the client. -*/ - -static void -send_xml_data (TSession * const r, - char * const buffer, - uint64 const len) { - - const char * const http_cookie = NULL; - /* This used to set http_cookie to getenv("HTTP_COOKIE"), but - that doesn't make any sense -- environment variables are not - appropriate for this. So for now, cookie code is disabled. - - Bryan 2004.10.03. - */ - - /* fwrite(buffer, sizeof(char), len, stderr); */ - - /* XXX - Is it safe to chunk our response? */ - ResponseChunked(r); - - ResponseStatus(r, 200); - - if (http_cookie) { - /* There's an auth cookie, so pass it back in the response. */ - - char *cookie_response; - - cookie_response = malloc(10+strlen(http_cookie)); - sprintf(cookie_response, "auth=%s", http_cookie); - - /* Return abyss response. */ - ResponseAddField(r, "Set-Cookie", cookie_response); - - free(cookie_response); - } - - - ResponseContentType(r, "text/xml; charset=\"utf-8\""); - ResponseContentLength(r, len); - - ResponseWrite(r); - - HTTPWrite(r, buffer, len); - HTTPWriteEnd(r); -} - - - -/*========================================================================= -** send_error -**========================================================================= -** Send an error back to the client. -*/ - -static void -send_error(TSession * const abyssSessionP, - unsigned int const status) { - - ResponseStatus(abyssSessionP, (uint16) status); - ResponseError(abyssSessionP); -} - - - -/*========================================================================= -** get_buffer_data -**========================================================================= -** Extract some data from the TConn's underlying input buffer. Do not -** extract more than 'max'. -*/ - -static void -get_buffer_data(TSession * const r, - int const max, - char ** const out_start, - int * const out_len) { - - /* Point to the start of our data. */ - *out_start = &r->conn->buffer[r->conn->bufferpos]; - - /* Decide how much data to retrieve. */ - *out_len = r->conn->buffersize - r->conn->bufferpos; - if (*out_len > max) - *out_len = max; - - /* Update our buffer position. */ - r->conn->bufferpos += *out_len; -} - - - -/*========================================================================= -** get_body -**========================================================================= -** Slurp the body of the request into an xmlrpc_mem_block. -*/ - -static void -getBody(xmlrpc_env * const envP, - TSession * const abyssSessionP, - unsigned int const contentSize, - xmlrpc_mem_block ** const bodyP) { -/*---------------------------------------------------------------------------- - Get the entire body from the Abyss session and return it as the new - memblock *bodyP. - - The first chunk of the body may already be in Abyss's buffer. We - retrieve that before reading more. ------------------------------------------------------------------------------*/ - xmlrpc_mem_block * body; - - body = xmlrpc_mem_block_new(envP, 0); - if (!envP->fault_occurred) { - unsigned int bytesRead; - char * chunkPtr; - int chunkLen; - - bytesRead = 0; - - while (!envP->fault_occurred && bytesRead < contentSize) { - get_buffer_data(abyssSessionP, contentSize - bytesRead, - &chunkPtr, &chunkLen); - bytesRead += chunkLen; - - XMLRPC_TYPED_MEM_BLOCK_APPEND(char, envP, body, - chunkPtr, chunkLen); - - if (bytesRead < contentSize) { - /* Get the next chunk of data from the connection into the - buffer - */ - abyss_bool succeeded; - - /* Reset our read buffer & flush data from previous reads. */ - ConnReadInit(abyssSessionP->conn); - - /* Read more network data into our buffer. If we encounter - a timeout, exit immediately. We're very forgiving about - the timeout here. We allow a full timeout per network - read, which would allow somebody to keep a connection - alive nearly indefinitely. But it's hard to do anything - intelligent here without very complicated code. - */ - succeeded = ConnRead(abyssSessionP->conn, - abyssSessionP->server->timeout); - if (!succeeded) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TIMEOUT_ERROR, "Timed out waiting for " - "client to send its POST data"); - } - } - if (envP->fault_occurred) - xmlrpc_mem_block_free(body); - else - *bodyP = body; - } -} - - - -static void -storeCookies(TSession * const httpRequestP, - unsigned int * const httpErrorP) { -/*---------------------------------------------------------------------------- - Get the cookie settings from the HTTP headers and remember them for - use in responses. ------------------------------------------------------------------------------*/ - const char * const cookie = RequestHeaderValue(httpRequestP, "cookie"); - if (cookie) { - /* - Setting the value in an environment variable doesn't make - any sense. So for now, cookie code is disabled. - -Bryan 04.10.03. - - setenv("HTTP_COOKIE", cookie, 1); - */ - } - /* TODO: parse HTTP_COOKIE to find auth pair, if there is one */ - - *httpErrorP = 0; -} - - - - -static void -validateContentType(TSession * const httpRequestP, - unsigned int * const httpErrorP) { -/*---------------------------------------------------------------------------- - If the client didn't specify a content-type of "text/xml", return - "400 Bad Request". We can't allow the client to default this header, - because some firewall software may rely on all XML-RPC requests - using the POST method and a content-type of "text/xml". ------------------------------------------------------------------------------*/ - const char * const content_type = - RequestHeaderValue(httpRequestP, "content-type"); - if (content_type == NULL || strcmp(content_type, "text/xml") != 0) - *httpErrorP = 400; - else - *httpErrorP = 0; -} - - - -static void -processContentLength(TSession * const httpRequestP, - unsigned int * const inputLenP, - unsigned int * const httpErrorP) { -/*---------------------------------------------------------------------------- - Make sure the content length is present and non-zero. This is - technically required by XML-RPC, but we only enforce it because we - don't want to figure out how to safely handle HTTP < 1.1 requests - without it. If the length is missing, return "411 Length Required". ------------------------------------------------------------------------------*/ - const char * const content_length = - RequestHeaderValue(httpRequestP, "content-length"); - if (content_length == NULL) - *httpErrorP = 411; - else { - int const contentLengthValue = atoi(content_length); - if (contentLengthValue <= 0) - *httpErrorP = 400; - else { - *httpErrorP = 0; - *inputLenP = (unsigned int)contentLengthValue; - } - } -} - - -/**************************************************************************** - Abyss handlers (to be registered with and called by Abyss) -****************************************************************************/ - -/* XXX - This variable is *not* currently threadsafe. Once the server has -** been started, it must be treated as read-only. */ -static xmlrpc_registry *global_registryP; - -static const char * trace_abyss; - -static void -processCall(TSession * const abyssSessionP, - int const inputLen) { -/*---------------------------------------------------------------------------- - Handle an RPC request. This is an HTTP request that has the proper form - to be one of our RPCs. ------------------------------------------------------------------------------*/ - xmlrpc_env env; - - if (trace_abyss) - fprintf(stderr, "xmlrpc_server_abyss RPC2 handler processing RPC.\n"); - - xmlrpc_env_init(&env); - - /* SECURITY: Make sure our content length is legal. - XXX - We can cast 'inputLen' because we know it's >= 0, yes? - */ - if ((size_t) inputLen > xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID)) - xmlrpc_env_set_fault_formatted( - &env, XMLRPC_LIMIT_EXCEEDED_ERROR, - "XML-RPC request too large (%d bytes)", inputLen); - else { - xmlrpc_mem_block *body; - /* Read XML data off the wire. */ - getBody(&env, abyssSessionP, inputLen, &body); - if (!env.fault_occurred) { - xmlrpc_mem_block * output; - /* Process the RPC. */ - output = xmlrpc_registry_process_call( - &env, global_registryP, NULL, - XMLRPC_MEMBLOCK_CONTENTS(char, body), - XMLRPC_MEMBLOCK_SIZE(char, body)); - if (!env.fault_occurred) { - /* Send our the result. */ - send_xml_data(abyssSessionP, - XMLRPC_MEMBLOCK_CONTENTS(char, output), - XMLRPC_MEMBLOCK_SIZE(char, output)); - - XMLRPC_MEMBLOCK_FREE(char, output); - } - XMLRPC_MEMBLOCK_FREE(char, body); - } - } - if (env.fault_occurred) { - if (env.fault_code == XMLRPC_TIMEOUT_ERROR) - send_error(abyssSessionP, 408); /* 408 Request Timeout */ - else - send_error(abyssSessionP, 500); /* 500 Internal Server Error */ - } - - xmlrpc_env_clean(&env); -} - - - -/*========================================================================= -** xmlrpc_server_abyss_rpc2_handler -**========================================================================= -** This handler processes all requests to '/RPC2'. See the header for -** more documentation. -*/ - -xmlrpc_bool -xmlrpc_server_abyss_rpc2_handler (TSession * const r) { - - xmlrpc_bool retval; - - if (trace_abyss) - fprintf(stderr, "xmlrpc_server_abyss RPC2 handler called.\n"); - - /* We handle only requests to /RPC2, the default XML-RPC URL. - Everything else we pass through to other handlers. - */ - if (strcmp(r->uri, "/RPC2") != 0) - retval = FALSE; - else { - retval = TRUE; - - /* We understand only the POST HTTP method. For anything else, return - "405 Method Not Allowed". - */ - if (r->method != m_post) - send_error(r, 405); - else { - unsigned int httpError; - storeCookies(r, &httpError); - if (httpError) - send_error(r, httpError); - else { - unsigned int httpError; - validateContentType(r, &httpError); - if (httpError) - send_error(r, httpError); - else { - unsigned int httpError; - int inputLen; - - processContentLength(r, &inputLen, &httpError); - if (httpError) - send_error(r, httpError); - - processCall(r, inputLen); - } - } - } - } - if (trace_abyss) - fprintf(stderr, "xmlrpc_server_abyss RPC2 handler returning.\n"); - return retval; -} - - - -/*========================================================================= -** xmlrpc_server_abyss_default_handler -**========================================================================= -** This handler returns a 404 Not Found for all requests. See the header -** for more documentation. -*/ - -xmlrpc_bool -xmlrpc_server_abyss_default_handler (TSession * const r) { - send_error(r, 404); - - return TRUE; -} - - - -/************************************************************************** -** -** The code below was adapted from the main.c file of the Abyss webserver -** project. In addition to the other copyrights on this file, the following -** code is also under this copyright: -** -** Copyright (C) 2000 by Moez Mahfoudh . -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. -** -**************************************************************************/ - -#include -#include - -#ifdef _WIN32 -#include -#else -/* Must check this -#include -*/ -#endif /* _WIN32 */ - -#ifdef _UNIX -#include -#include -#include -#endif - - -#ifdef _UNIX -static void -sigterm(int const sig) { - TraceExit("Signal %d received. Exiting...\n",sig); -} -#endif - - -#ifdef _UNIX -static void -sigchld(int const sig ATTR_UNUSED) { -/*---------------------------------------------------------------------------- - This is a signal handler for a SIGCHLD signal (which informs us that - one of our child processes has terminated). - - We respond by reaping the zombie process. - - Implementation note: In some systems, just setting the signal handler - to SIG_IGN (ignore signal) does this. In others, it doesn't. ------------------------------------------------------------------------------*/ - pid_t pid; - int status; - - /* Reap defunct children until there aren't any more. */ - for (;;) { - pid = waitpid( (pid_t) -1, &status, WNOHANG ); - - /* none left */ - if (pid==0) - break; - - if (pid<0) { - /* because of ptrace */ - if (errno==EINTR) - continue; - - break; - } - } -} -#endif /* _UNIX */ - -static TServer globalSrv; - /* When you use the old interface (xmlrpc_server_abyss_init(), etc.), - this is the Abyss server to which they refer. Obviously, there can be - only one Abyss server per program using this interface. - */ - - -void -xmlrpc_server_abyss_init(int const flags ATTR_UNUSED, - const char * const config_file) { - - DateInit(); - MIMETypeInit(); - - ServerCreate(&globalSrv, "XmlRpcServer", 8080, DEFAULT_DOCS, NULL); - - ConfReadServerFile(config_file, &globalSrv); - - xmlrpc_server_abyss_init_registry(); - /* Installs /RPC2 handler and default handler that use the - built-in registry. - */ - - ServerInit(&globalSrv); -} - - - -static void -setupSignalHandlers(void) { -#ifdef _UNIX - struct sigaction mysigaction; - - sigemptyset(&mysigaction.sa_mask); - mysigaction.sa_flags = 0; - - /* These signals abort the program, with tracing */ - mysigaction.sa_handler = sigterm; - sigaction(SIGTERM, &mysigaction, NULL); - sigaction(SIGINT, &mysigaction, NULL); - sigaction(SIGHUP, &mysigaction, NULL); - sigaction(SIGUSR1, &mysigaction, NULL); - - /* This signal indicates connection closed in the middle */ - mysigaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &mysigaction, NULL); - - /* This signal indicates a child process (request handler) has died */ - mysigaction.sa_handler = sigchld; - sigaction(SIGCHLD, &mysigaction, NULL); -#endif -} - - - -static void -runServer(TServer * const srvP, - runfirstFn const runfirst, - void * const runfirstArg) { - - setupSignalHandlers(); - -#ifdef _UNIX - /* Become a daemon */ - switch (fork()) { - case 0: - break; - case -1: - TraceExit("Unable to become a daemon"); - default: - exit(0); - }; - - setsid(); - - /* Change the current user if we are root */ - if (getuid()==0) { - if (srvP->uid == (uid_t)-1) - TraceExit("Can't run under root privileges. " - "Please add a User option in your " - "Abyss configuration file."); - -#ifdef HAVE_SETGROUPS - if (setgroups(0,NULL)==(-1)) - TraceExit("Failed to setup the group."); - if (srvP->gid != (gid_t)-1) - if (setgid(srvP->gid)==(-1)) - TraceExit("Failed to change the group."); -#endif - - if (setuid(srvP->uid) == -1) - TraceExit("Failed to change the user."); - }; - - if (srvP->pidfile!=(-1)) { - char z[16]; - - sprintf(z,"%d",getpid()); - FileWrite(&srvP->pidfile,z,strlen(z)); - FileClose(&srvP->pidfile); - }; -#endif - - /* We run the user supplied runfirst after forking, but before accepting - connections (helpful when running with threads) - */ - if (runfirst) - runfirst(runfirstArg); - - ServerRun(srvP); - - /* We can't exist here because ServerRun doesn't return */ - XMLRPC_ASSERT(FALSE); -} - - - -void -xmlrpc_server_abyss_run_first(runfirstFn const runfirst, - void * const runfirstArg) { - - runServer(&globalSrv, runfirst, runfirstArg); -} - - - -void -xmlrpc_server_abyss_run(void) { - runServer(&globalSrv, NULL, NULL); -} - - - -void -xmlrpc_server_abyss_set_handlers(TServer * const srvP, - xmlrpc_registry * const registryP) { - - /* Abyss ought to have a way to register with a handler an argument - that gets passed to the handler every time it is called. That's - where we should put the registry handle. But we don't find such - a thing in Abyss, so we use the global variable 'global_registryP'. - */ - global_registryP = registryP; - - trace_abyss = getenv("XMLRPC_TRACE_ABYSS"); - - ServerAddHandler(srvP, xmlrpc_server_abyss_rpc2_handler); - ServerDefaultHandler(srvP, xmlrpc_server_abyss_default_handler); -} - - - -void -xmlrpc_server_abyss(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parmsP, - unsigned int const parm_size) { - - XMLRPC_ASSERT_ENV_OK(envP); - - if (parm_size < XMLRPC_APSIZE(registryP)) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INTERNAL_ERROR, - "You must specify members at least up through " - "'registryP' in the server parameters argument. " - "That would mean the parameter size would be >= %u " - "but you specified a size of %u", - XMLRPC_APSIZE(registryP), parm_size); - else { - TServer srv; - runfirstFn runfirst; - void * runfirstArg; - - DateInit(); - MIMETypeInit(); - - ServerCreate(&srv, "XmlRpcServer", 8080, DEFAULT_DOCS, NULL); - - ConfReadServerFile(parmsP->config_file_name, &srv); - - xmlrpc_server_abyss_set_handlers(&srv, parmsP->registryP); - - ServerInit(&srv); - - if (parm_size >= XMLRPC_APSIZE(runfirst_arg)) { - runfirst = parmsP->runfirst; - runfirstArg = parmsP->runfirst_arg; - } else { - runfirst = NULL; - runfirstArg = NULL; - } - runServer(&srv, runfirst, runfirstArg); - } -} - - - -/*========================================================================= -** XML-RPC Server Method Registry -**========================================================================= -** A simple front-end to our method registry. -*/ - -/* XXX - This variable is *not* currently threadsafe. Once the server has -** been started, it must be treated as read-only. */ -static xmlrpc_registry *builtin_registryP; - -void -xmlrpc_server_abyss_init_registry(void) { - - /* This used to just create the registry and Caller would be - responsible for adding the handlers that use it. - - But that isn't very modular -- the handlers and registry go - together; there's no sense in using the built-in registry and - not the built-in handlers because if you're custom building - something, you can just make your own regular registry. So now - we tie them together, and we don't export our handlers. - */ - xmlrpc_env env; - - xmlrpc_env_init(&env); - builtin_registryP = xmlrpc_registry_new(&env); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); - - xmlrpc_server_abyss_set_handlers(&globalSrv, builtin_registryP); -} - - - -xmlrpc_registry * -xmlrpc_server_abyss_registry(void) { - - /* This is highly deprecated. If you want to mess with a registry, - make your own with xmlrpc_registry_new() -- don't mess with the - internal one. - */ - return builtin_registryP; -} - - - -/* A quick & easy shorthand for adding a method. */ -void -xmlrpc_server_abyss_add_method (char * const method_name, - xmlrpc_method const method, - void * const user_data) { - xmlrpc_env env; - - xmlrpc_env_init(&env); - xmlrpc_registry_add_method(&env, builtin_registryP, NULL, method_name, - method, user_data); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} - - - -void -xmlrpc_server_abyss_add_method_w_doc (char * const method_name, - xmlrpc_method const method, - void * const user_data, - char * const signature, - char * const help) { - - xmlrpc_env env; - xmlrpc_env_init(&env); - xmlrpc_registry_add_method_w_doc( - &env, builtin_registryP, NULL, method_name, - method, user_data, signature, help); - die_if_fault_occurred(&env); - xmlrpc_env_clean(&env); -} diff --git a/Utilities/cmxmlrpc/xmlrpc_server_abyss.h b/Utilities/cmxmlrpc/xmlrpc_server_abyss.h deleted file mode 100644 index 95676fd9b4..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_server_abyss.h +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#ifndef _XMLRPC_SERVER_ABYSS_H_ -#define _XMLRPC_SERVER_ABYSS_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -struct _TServer; - -/*========================================================================= -** XML-RPC Server (based on Abyss) -**========================================================================= -** A simple XML-RPC server based on the Abyss web server. If errors -** occur during server setup, the server will exit. In general, if you -** want to use this API, you'll need to be familiar with Abyss. -** -** There are two ways to use Abyss: -** 1) You can use the handy wrapper functions. -** 2) You can set up Abyss yourself, and install the appropriate -** handlers manually. -*/ - -#define XMLRPC_SERVER_ABYSS_NO_FLAGS (0) - - - - -/*========================================================================= -** Basic Abyss Server Functions -**=======================================================================*/ - -typedef void ((*runfirstFn)(void *)); - -typedef struct { - const char * config_file_name; - xmlrpc_registry * registryP; - runfirstFn runfirst; - void * runfirst_arg; -} xmlrpc_server_abyss_parms; - - -#define XMLRPC_APSIZE(MBRNAME) \ - XMLRPC_STRUCTSIZE(xmlrpc_server_abyss_parms, MBRNAME) - -/* XMLRPC_APSIZE(xyz) is the minimum size a struct xmlrpc_server_abyss_parms - must be to include the 'xyz' member. This is essential to forward and - backward compatbility, as new members will be added to the end of the - struct in future releases. This is how the callee knows whether or - not the caller is new enough to have supplied a certain parameter. -*/ - -void -xmlrpc_server_abyss(xmlrpc_env * const envP, - const xmlrpc_server_abyss_parms * const parms, - unsigned int const parm_size); - -void -xmlrpc_server_abyss_set_handlers(struct _TServer * const srvP, - xmlrpc_registry * const registryP); - - -/*========================================================================= -** Handy Abyss Extensions -**=======================================================================*/ - -/* These are functions that have nothing to do with Xmlrpc-c, but provide - convenient Abyss services beyond those provided by the Abyss library. -*/ - -/* Start an Abyss webserver running (previously created and -** initialized). Under Unix, this routine will attempt to do a -** detaching fork, drop root privileges (if any) and create a pid -** file. Under Windows, this routine merely starts the server. This -** routine never returns. -** -** Once you call this routine, it is illegal to modify the server any -** more, including changing any method registry. -*/ -void -xmlrpc_server_abyss_run(void); - -/* Same as xmlrpc_server_abyss_run(), except you get to specify a "runfirst" -** function. The server runs this just before executing the actual server -** function, after any daemonizing. NULL for 'runfirst' means no runfirst -** function. 'runfirstArg' is the argument the server passes to the runfirst -** function. -**/ -void -xmlrpc_server_abyss_run_first(void (runfirst(void *)), - void * const runfirstArg); - -/*========================================================================= -** Method Registry -**========================================================================= - These functions are for the built-in xmlrpc_server_abyss registry. - It's usually simpler to skip all this and use the regular method - registry services (from xmlrpc_server.h) to build a registry and - pass it to xmlrpc_server_abyss. -*/ - -/* Call this function to create a new Abyss webserver with the default -** options and the built-in method registry. If you've already -** initialized Abyss using Abyss functions, you can instead call -** xmlrpc_server_abyss_init_registry() to make it an Xmlrpc-c server. -** Or use a regular method registry and call -** xmlrpc_server_abyss_set_handlers(). -**/ -void -xmlrpc_server_abyss_init(int const flags, - const char * const config_file); - -/* This is called automatically by xmlrpc_server_abyss_init. */ -void xmlrpc_server_abyss_init_registry (void); - -/* Fetch the internal registry, if you happen to need it. - If you're using this, you really shouldn't be using the built-in - registry at all. It exists today only for backward compatibilty. -*/ -extern xmlrpc_registry * -xmlrpc_server_abyss_registry (void); - -/* A quick & easy shorthand for adding a method. Depending on -** how you've configured your copy of Abyss, it's probably not safe to -** call this method after calling xmlrpc_server_abyss_run. */ -void xmlrpc_server_abyss_add_method (char *method_name, - xmlrpc_method method, - void *user_data); - -/* As above, but provide documentation (see xmlrpc_registry_add_method_w_doc -** for more information). You should really use this one. */ -extern void -xmlrpc_server_abyss_add_method_w_doc (char *method_name, - xmlrpc_method method, - void *user_data, - char *signature, - char *help); - -/*========================================================================= -** Content Handlers -**=======================================================================*/ -/* Abyss contents handlers xmlrpc_server_abyss_rpc2_handler() - and xmlrpc_server_abyss_default_handler() were available in older - Xmlrpc-c, but starting with Release 1.01, they are not. Instead, - call xmlrpc_server_abyss_set_handlers() to install them. - - Alternatively, you can write your own handlers that do the same thing. - It's not hard, and if you're writing low enough level Abyss code that - you can't use xmlrpc_server_abyss_set_handlers(), you probably want to - anyway. -*/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_server_abyss_int.h b/Utilities/cmxmlrpc/xmlrpc_server_abyss_int.h deleted file mode 100644 index 06cb17c458..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_server_abyss_int.h +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - xmlrpc_server_abyss_int.h -============================================================================== - This header file defines the interface between client modules inside - xmlrpc-c. - - Use this in addition to xmlrpc_server_abyss.h, which defines the external - interface. - - Copyright information is at the end of the file. -============================================================================*/ - -#ifndef _XMLRPC_SERVER_ABYSS_INT_H_ -#define _XMLRPC_SERVER_ABYSS_INT_H_ 1 - -#include "abyss.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/*========================================================================= -** Abyss Content Handlers -**========================================================================= -** These are Abyss handlers. You install them into an Abyss server. -*/ - -/* Handler for XML-RPC requests. Install this using ServerAddHandler - as the handler for all requests to /RPC2. This handler assumes that - it can read from the method registry without running into race - conditions or anything nasty like that. -*/ -extern xmlrpc_bool -xmlrpc_server_abyss_rpc2_handler (TSession *r); - -/* A default handler. Install this as the default handler with - ServerDefaultHandler if you don't want to serve any HTML or - GIFs from your htdocs directory. - - This handler always returns a "404 Not Found". -*/ -extern xmlrpc_bool -xmlrpc_server_abyss_default_handler (TSession *r); - - - - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - diff --git a/Utilities/cmxmlrpc/xmlrpc_struct.c b/Utilities/cmxmlrpc/xmlrpc_struct.c deleted file mode 100644 index 50cc6dbd3e..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_struct.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" - -#define KEY_ERROR_BUFFER_SZ (32) - - -void -xmlrpc_destroyStruct(xmlrpc_value * const structP) { - - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); - - unsigned int i; - - for (i = 0; i < size; ++i) { - xmlrpc_DECREF(members[i].key); - xmlrpc_DECREF(members[i].value); - } - XMLRPC_MEMBLOCK_CLEAN(_struct_member, &structP->_block); -} - - - -/*========================================================================= -** xmlrpc_struct_new -**========================================================================= -** Create a new value. The corresponding destructor code -** currently lives in xmlrpc_DECREF. -** -** We store the individual members in an array of _struct_member. This -** contains a key, a hash code, and a value. We look up keys by doing -** a linear search of the hash codes. -*/ - -xmlrpc_value * -xmlrpc_struct_new(xmlrpc_env* env) -{ - xmlrpc_value *strct; - int strct_valid; - - XMLRPC_ASSERT_ENV_OK(env); - - /* Set up error handling preconditions. */ - strct_valid = 0; - - /* Allocate and fill out an empty structure. */ - strct = (xmlrpc_value*) malloc(sizeof(xmlrpc_value)); - XMLRPC_FAIL_IF_NULL(strct, env, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for struct"); - strct->_refcount = 1; - strct->_type = XMLRPC_TYPE_STRUCT; - XMLRPC_MEMBLOCK_INIT(_struct_member, env, &strct->_block, 0); - XMLRPC_FAIL_IF_FAULT(env); - strct_valid = 1; - - cleanup: - if (env->fault_occurred) { - if (strct) { - if (strct_valid) - xmlrpc_DECREF(strct); - else - free(strct); - } - return NULL; - } - return strct; -} - - - -/*========================================================================= -** xmlrpc_struct_size -**========================================================================= -** Return the number of key-value pairs contained in the struct. If the -** value is not a struct, return -1 and set a fault. -*/ - -int -xmlrpc_struct_size(xmlrpc_env* env, xmlrpc_value* strct) -{ - int retval; - - /* Suppress a compiler warning about uninitialized variables. */ - retval = 0; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(strct); - - XMLRPC_TYPE_CHECK(env, strct, XMLRPC_TYPE_STRUCT); - retval = (int)XMLRPC_MEMBLOCK_SIZE(_struct_member, &strct->_block); - - cleanup: - if (env->fault_occurred) - return -1; - return retval; -} - - - -/*========================================================================= -** get_hash -**========================================================================= -** A mindlessly simple hash function. Please feel free to write something -** more clever if this produces bad results. -*/ - -static unsigned char -get_hash(const char * const key, - size_t const key_len) { - - unsigned char retval; - size_t i; - - XMLRPC_ASSERT(key != NULL); - - retval = 0; - for (i = 0; i < key_len; i++) - retval += key[i]; - return retval; -} - - - -/*========================================================================= -** find_member -**========================================================================= -** Get the index of the member with the specified key, or -1 if no such -** member exists. -*/ - -static int -find_member(xmlrpc_value * const strctP, - const char * const key, - size_t const key_len) { - - size_t size, i; - unsigned char hash; - _struct_member *contents; - xmlrpc_value *keyval; - char *keystr; - size_t keystr_size; - - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT(key != NULL); - - /* Look for our key. */ - hash = get_hash(key, key_len); - size = XMLRPC_MEMBLOCK_SIZE(_struct_member, &strctP->_block); - contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block); - for (i = 0; i < size; i++) { - if (contents[i].key_hash == hash) { - keyval = contents[i].key; - keystr = XMLRPC_MEMBLOCK_CONTENTS(char, &keyval->_block); - keystr_size = XMLRPC_MEMBLOCK_SIZE(char, &keyval->_block)-1; - if (key_len == keystr_size && memcmp(key, keystr, key_len) == 0) - return (int)i; - } - } - return -1; -} - - - -/*========================================================================= -** xmlrpc_struct_has_key -**========================================================================= -*/ - -int -xmlrpc_struct_has_key(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_has_key_n(envP, strctP, key, strlen(key)); -} - - - -int -xmlrpc_struct_has_key_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len) { - int xmIndex; - - /* Suppress a compiler warning about uninitialized variables. */ - xmIndex = 0; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT(key != NULL); - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - xmIndex = find_member(strctP, key, key_len); - - cleanup: - if (envP->fault_occurred) - return 0; - return (xmIndex >= 0); -} - - - -/*========================================================================= -** xmlrpc_struct_find_value... -**========================================================================= -** These functions look up a specified key value in a specified struct. -** If it exists, they return the value of the struct member. If not, -** they return a NULL to indicate such. -*/ - -/* It would be a nice extension to be able to look up a key that is - not a text string. -*/ - -void -xmlrpc_struct_find_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(key); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - int xmIndex; - - /* Get our member index. */ - xmIndex = find_member(structP, key, strlen(key)); - if (xmIndex < 0) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - *valuePP = members[xmIndex].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } -} - - - -void -xmlrpc_struct_find_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_VALUE_OK(keyP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - if (keyP->_type != XMLRPC_TYPE_STRING) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Key value is not a string. " - "It is type #%d", - keyP->_type); - else { - int xmIndex; - - /* Get our member index. */ - xmIndex = find_member(structP, - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block), - XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block)-1); - if (xmIndex < 0) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - *valuePP = members[xmIndex].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_read_value... -**========================================================================= -** These fail if no member with the specified key exists. -** Otherwise, they are the same as xmlrpc_struct_find_value... -*/ - -void -xmlrpc_struct_read_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value_v(envP, structP, keyP, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%.*s'", - XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block), - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block)); - } - } -} - - - -void -xmlrpc_struct_read_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value(envP, structP, key, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%s'", - key); - /* We should fix the error message to format the key for display */ - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_get_value... -**========================================================================= -** These are for backward compatibility. They used to be the only ones. -** They're deprecated because they don't acquire a reference to the -** value they return. -*/ - -xmlrpc_value * -xmlrpc_struct_get_value_n(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - size_t const keyLen) { - - xmlrpc_value * retval; - xmlrpc_value * keyP; - - keyP = xmlrpc_build_value(envP, "s#", key, keyLen); - if (!envP->fault_occurred) { - xmlrpc_struct_find_value_v(envP, structP, keyP, &retval); - - if (!envP->fault_occurred) { - if (retval == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "No member of struct has key '%.*s'", - keyLen, key); - /* We should fix the error message to format the key - for display */ - } else - /* For backward compatibility. */ - xmlrpc_DECREF(retval); - } - xmlrpc_DECREF(keyP); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_struct_get_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_get_value_n(envP, strctP, key, strlen(key)); -} - - - -/*========================================================================= -** xmlrpc_struct_set_value -**========================================================================= -*/ - -void -xmlrpc_struct_set_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT(key != NULL); - xmlrpc_struct_set_value_n(envP, strctP, key, strlen(key), valueP); -} - - - -void -xmlrpc_struct_set_value_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len, - xmlrpc_value * const valueP) { - - xmlrpc_value *keyval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(key != NULL); - - /* Set up error handling preconditions. */ - keyval = NULL; - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - - /* Build an xmlrpc_value from our string. */ - keyval = xmlrpc_build_value(envP, "s#", key, key_len); - XMLRPC_FAIL_IF_FAULT(envP); - - /* Do the actual work. */ - xmlrpc_struct_set_value_v(envP, strctP, keyval, valueP); - - cleanup: - if (keyval) - xmlrpc_DECREF(keyval); -} - - - -void -xmlrpc_struct_set_value_v(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - xmlrpc_value * const keyvalP, - xmlrpc_value * const valueP) { - - char *key; - size_t key_len; - int xmIndex; - _struct_member *members, *member, new_member; - xmlrpc_value *old_value; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT_VALUE_OK(keyvalP); - XMLRPC_ASSERT_VALUE_OK(valueP); - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - XMLRPC_TYPE_CHECK(envP, keyvalP, XMLRPC_TYPE_STRING); - - key = XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block); - key_len = XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block) - 1; - xmIndex = find_member(strctP, key, key_len); - - if (xmIndex >= 0) { - /* Change the value of an existing member. (But be careful--the - ** original and new values might be the same object, so watch - ** the order of INCREF and DECREF calls!) */ - members = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block); - member = &members[xmIndex]; - - /* Juggle our references. */ - old_value = member->value; - member->value = valueP; - xmlrpc_INCREF(member->value); - xmlrpc_DECREF(old_value); - } else { - /* Add a new member. */ - new_member.key_hash = get_hash(key, key_len); - new_member.key = keyvalP; - new_member.value = valueP; - XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, &strctP->_block, - &new_member, 1); - XMLRPC_FAIL_IF_FAULT(envP); - xmlrpc_INCREF(keyvalP); - xmlrpc_INCREF(valueP); - } - -cleanup: - return; -} - - - -/* Note that the order of keys and values is undefined, and may change - when you modify the struct. -*/ - -void -xmlrpc_struct_read_member(xmlrpc_env * const envP, - xmlrpc_value * const structP, - unsigned int const xmIndex, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Attempt to read a struct member " - "of something that is not a struct"); - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); - - if (xmIndex >= size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %u is beyond the end of " - "the %u-member structure", xmIndex, (unsigned int)size); - else { - _struct_member * const memberP = &members[xmIndex]; - *keyvalP = memberP->key; - xmlrpc_INCREF(memberP->key); - *valueP = memberP->value; - xmlrpc_INCREF(memberP->value); - } - } -} - - - -void -xmlrpc_struct_get_key_and_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - int const xmIndex, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { -/*---------------------------------------------------------------------------- - Same as xmlrpc_struct_read_member(), except doesn't take a reference - to the returned value. - - This is obsolete. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (xmIndex < 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %d is negative."); - else { - xmlrpc_struct_read_member(envP, structP, xmIndex, keyvalP, valueP); - if (!envP->fault_occurred) { - xmlrpc_DECREF(*keyvalP); - xmlrpc_DECREF(*valueP); - } - } - if (envP->fault_occurred) { - *keyvalP = NULL; - *valueP = NULL; - } -} diff --git a/Utilities/cmxmlrpc/xmlrpc_strutil.c b/Utilities/cmxmlrpc/xmlrpc_strutil.c deleted file mode 100644 index 8efdb4072b..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_strutil.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include - -#include "xmlrpc.h" -#include "xmlrpc_int.h" -#include "xmlrpc_config.h" - - - -const char * -xmlrpc_makePrintable(const char * const input) { -/*---------------------------------------------------------------------------- - Convert an arbitrary string of bytes (null-terminated, though) to - printable ASCII. E.g. convert newlines to "\n". - - Return the result in newly malloc'ed storage. Return NULL if we can't - get the storage. ------------------------------------------------------------------------------*/ - char * output; - const size_t inputLength = strlen(input); - - output = malloc(inputLength*4+1); - - if (output != NULL) { - unsigned int inputCursor, outputCursor; - - for (inputCursor = 0, outputCursor = 0; - inputCursor < inputLength; - ++inputCursor) { - - if (isprint((int)(input[inputCursor]))) - output[outputCursor++] = input[inputCursor]; - else if (input[inputCursor] == '\n') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'n'; - } else if (input[inputCursor] == '\t') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 't'; - } else if (input[inputCursor] == '\a') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'a'; - } else if (input[inputCursor] == '\r') { - output[outputCursor++] = '\\'; - output[outputCursor++] = 'r'; - } else { - snprintf(&output[outputCursor], 4, "\\x%02x", - input[inputCursor]); - } - } - output[outputCursor+1] = '\0'; - } - return output; -} - - - -const char * -xmlrpc_makePrintableChar(char const input) { - - const char * retval; - - if (input == '\0') - retval = strdup("\\0"); - else { - char buffer[2]; - - buffer[0] = input; - buffer[1] = '\0'; - - retval = xmlrpc_makePrintable(buffer); - } - return retval; -} diff --git a/Utilities/cmxmlrpc/xmlrpc_support.c b/Utilities/cmxmlrpc/xmlrpc_support.c deleted file mode 100644 index ac29a12eca..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_support.c +++ /dev/null @@ -1,367 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#include -#include -#include -#include - -#ifdef WIN32 -# define vsnprintf _vsnprintf -#endif - -#include "xmlrpc.h" -#include "xmlrpc_int.h" - -#ifdef EFENCE - /* when looking for corruption don't allocate extra slop */ -#define BLOCK_ALLOC_MIN (1) -#else -#define BLOCK_ALLOC_MIN (16) -#endif -#define BLOCK_ALLOC_MAX (128 * 1024 * 1024) - -#define ERROR_BUFFER_SZ (256) - - -/*========================================================================= -** Strings -**=======================================================================*/ - -void -xmlrpc_strfree(const char * const string) { - free((void*)string); -} - - -/*========================================================================= -** Assertions and Error Handling -**========================================================================= -** Support code for XMLRPC_ASSERT and xmlrpc_env. -*/ - -void xmlrpc_assertion_failed (char* file, int line) -{ - fprintf(stderr, "%s:%d: assertion failed\n", file, line); - abort(); -} - -static char* default_fault_string = "Not enough memory for error message"; - -void xmlrpc_env_init (xmlrpc_env* env) -{ - XMLRPC_ASSERT(env != NULL); - - env->fault_occurred = 0; - env->fault_code = 0; - env->fault_string = NULL; -} - -void xmlrpc_env_clean (xmlrpc_env* env) -{ - XMLRPC_ASSERT(env != NULL); - - /* env->fault_string may be one of three things: - ** 1) a NULL pointer - ** 2) a pointer to the default_fault_string - ** 3) a pointer to a malloc'd fault string - ** If we have case (3), we'll need to free it. */ - if (env->fault_string && env->fault_string != default_fault_string) - free(env->fault_string); - env->fault_string = XMLRPC_BAD_POINTER; -} - - - -void -xmlrpc_env_set_fault(xmlrpc_env * const env, - int const faultCode, - const char * const faultDescription) { - - XMLRPC_ASSERT(env != NULL); - XMLRPC_ASSERT(faultDescription != NULL); - - /* Clean up any leftover pointers. */ - xmlrpc_env_clean(env); - - env->fault_occurred = 1; - env->fault_code = faultCode; - - /* Try to copy the fault string. If this fails, use a default. */ - env->fault_string = (char*) malloc(strlen(faultDescription) + 1); - if (env->fault_string) - strcpy(env->fault_string, faultDescription); - else - env->fault_string = default_fault_string; -} - - - -void -xmlrpc_env_set_fault_formatted (xmlrpc_env * const envP, - int const code, - const char * const format, - ...) { - va_list args; - char buffer[ERROR_BUFFER_SZ]; - - XMLRPC_ASSERT(envP != NULL); - XMLRPC_ASSERT(format != NULL); - - /* Print our error message to the buffer. */ - va_start(args, format); - vsnprintf(buffer, ERROR_BUFFER_SZ, format, args); - va_end(args); - - /* vsnprintf is guaranteed to terminate the buffer, but we're paranoid. */ - buffer[ERROR_BUFFER_SZ - 1] = '\0'; - - /* Set the fault. */ - xmlrpc_env_set_fault(envP, code, buffer); -} - - - -void xmlrpc_fatal_error (char* file, int line, char* msg) -{ - fprintf(stderr, "%s:%d: %s\n", file, line, msg); - exit(1); -} - - -/*========================================================================= -** Resource Limits -**========================================================================= -*/ - -static size_t limits[XMLRPC_LAST_LIMIT_ID + 1] = { - XMLRPC_NESTING_LIMIT_DEFAULT, - XMLRPC_XML_SIZE_LIMIT_DEFAULT -}; - -void xmlrpc_limit_set (int limit_id, size_t value) -{ - XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); - limits[limit_id] = value; -} - -size_t xmlrpc_limit_get (int limit_id) -{ - XMLRPC_ASSERT(0 <= limit_id && limit_id <= XMLRPC_LAST_LIMIT_ID); - return limits[limit_id]; -} - - -/*========================================================================= -** xmlrpc_mem_block -**========================================================================= -** We support resizable blocks of memory. We need these just about -** everywhere. -*/ - -xmlrpc_mem_block * -xmlrpc_mem_block_new(xmlrpc_env * const env, - size_t const size) { - xmlrpc_mem_block* block; - - XMLRPC_ASSERT_ENV_OK(env); - - block = (xmlrpc_mem_block*) malloc(sizeof(xmlrpc_mem_block)); - XMLRPC_FAIL_IF_NULL(block, env, XMLRPC_INTERNAL_ERROR, - "Can't allocate memory block"); - - xmlrpc_mem_block_init(env, block, size); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (env->fault_occurred) { - if (block) - free(block); - return NULL; - } else { - return block; - } -} - -/* Destroy an existing xmlrpc_mem_block, and everything it contains. */ -void xmlrpc_mem_block_free (xmlrpc_mem_block* block) -{ - XMLRPC_ASSERT(block != NULL); - XMLRPC_ASSERT(block->_block != NULL); - - xmlrpc_mem_block_clean(block); - free(block); -} - -/* Initialize the contents of the provided xmlrpc_mem_block. */ -void xmlrpc_mem_block_init (xmlrpc_env* env, - xmlrpc_mem_block* block, - size_t size) -{ - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(block != NULL); - - block->_size = size; - if (size < BLOCK_ALLOC_MIN) - block->_allocated = BLOCK_ALLOC_MIN; - else - block->_allocated = size; - - block->_block = (void*) malloc(block->_allocated); - if (!block->_block) - xmlrpc_env_set_fault_formatted( - env, XMLRPC_INTERNAL_ERROR, - "Can't allocate %u-byte memory block", - block->_allocated); -} - -/* Deallocate the contents of the provided xmlrpc_mem_block, but not the -** block itself. */ -void xmlrpc_mem_block_clean (xmlrpc_mem_block* block) -{ - XMLRPC_ASSERT(block != NULL); - XMLRPC_ASSERT(block->_block != NULL); - - free(block->_block); - block->_block = XMLRPC_BAD_POINTER; -} - - - -/* Get the size of the xmlrpc_mem_block. */ -size_t -xmlrpc_mem_block_size(const xmlrpc_mem_block * const block) { - - XMLRPC_ASSERT(block != NULL); - return block->_size; -} - - - -/* Get the contents of the xmlrpc_mem_block. */ -void * -xmlrpc_mem_block_contents(const xmlrpc_mem_block * const block) { - - XMLRPC_ASSERT(block != NULL); - return block->_block; -} - - - -/* Resize an xmlrpc_mem_block, preserving as much of the contents as -** possible. */ -void -xmlrpc_mem_block_resize (xmlrpc_env * const env, - xmlrpc_mem_block * const block, - size_t const size) { - - size_t proposed_alloc; - void* new_block; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(block != NULL); - - /* Check to see if we already have enough space. Maybe we'll get lucky. */ - if (size <= block->_allocated) { - block->_size = size; - return; - } - - /* Calculate a new allocation size. */ -#ifdef EFENCE - proposed_alloc = size; -#else - proposed_alloc = block->_allocated; - while (proposed_alloc < size && proposed_alloc <= BLOCK_ALLOC_MAX) - proposed_alloc *= 2; -#endif /* DEBUG_MEM_ERRORS */ - - if (proposed_alloc > BLOCK_ALLOC_MAX) - XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, "Memory block too large"); - - /* Allocate our new memory block. */ - new_block = (void*) malloc(proposed_alloc); - XMLRPC_FAIL_IF_NULL(new_block, env, XMLRPC_INTERNAL_ERROR, - "Can't resize memory block"); - - /* Copy over our data and update the xmlrpc_mem_block struct. */ - memcpy(new_block, block->_block, block->_size); - free(block->_block); - block->_block = new_block; - block->_size = size; - block->_allocated = proposed_alloc; - - cleanup: - return; -} - -/* Append data to an existing xmlrpc_mem_block. */ -void -xmlrpc_mem_block_append(xmlrpc_env * const env, - xmlrpc_mem_block * const block, - void * const data, - size_t const len) -{ - size_t size; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT(block != NULL); - - size = block->_size; - xmlrpc_mem_block_resize(env, block, size + len); - XMLRPC_FAIL_IF_FAULT(env); - - memcpy(((unsigned char*) block->_block) + size, data, len); - - cleanup: - return; -} - - - -void -xmlrpc_traceXml(const char * const label, - const char * const xml, - unsigned int const xmlLength) { - - if (getenv("XMLRPC_TRACE_XML")) { - unsigned int nonPrintableCount; - unsigned int i; - - nonPrintableCount = 0; /* Initial value */ - - for (i = 0; i < xmlLength; ++i) { - if (!isprint((int)(xml[i])) && xml[i] != '\n' && xml[i] != '\r') - ++nonPrintableCount; - } - if (nonPrintableCount > 0) - fprintf(stderr, "%s contains %u nonprintable characters.\n", - label, nonPrintableCount); - - fprintf(stderr, "%s:\n %.*s\n", label, (int)xmlLength, xml); - } -} diff --git a/Utilities/cmxmlrpc/xmlrpc_transport.c b/Utilities/cmxmlrpc/xmlrpc_transport.c deleted file mode 100644 index 3ae6e69b99..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_transport.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - -#include "xmlrpc_config.h" - -#undef PACKAGE -#undef VERSION - -#include -#include -#include - -#ifdef WIN32 -#ifdef _DEBUG -# include -# define new DEBUG_NEW -# define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) -# undef THIS_FILE - static char THIS_FILE[] = __FILE__; -#endif -#endif /*WIN32*/ - -#include "xmlrpc.h" -#include "xmlrpc_client.h" - -#if defined (WIN32) -#include -#endif - -/* For debugging the xmlrpc_transport threading. */ -/* #define tdbg_printf printf */ -#define tdbg_printf (void *) - -/* Lacking from the abyss/thread.c implimentaion. */ -void wait_for_asynch_thread(pthread_t *thread) -{ -#if WIN32 - unsigned long milliseconds = INFINITE; - switch (WaitForSingleObject ( - *thread /* handle to object to wait for */, - milliseconds /* time-out interval in milliseconds*/) ) - { - /* One may want to handle these cases */ - case WAIT_OBJECT_0: - case WAIT_TIMEOUT: - break; - } -#else - void * result; - int success; - success = pthread_join (*thread, &result); -#endif -} - -/* MRB-WARNING: Only call when you have successfully -** acquired the Lock/Unlock mutex! */ -void unregister_asynch_thread (running_thread_list *list, pthread_t *thread) -{ - running_thread_info * pCur = NULL; - XMLRPC_ASSERT_PTR_OK(thread); - XMLRPC_ASSERT_PTR_OK(list); - - tdbg_printf("unregister_asynch_thread: &pthread_id = %08X *(%08X)\n", thread, *thread); - /* Removal */ - /* Lock (); */ - for (pCur = list->AsyncThreadHead; pCur != NULL; pCur = (running_thread_info *)pCur->Next) - { - if (pCur->_thread == *thread) - { - if (pCur == list->AsyncThreadHead) - list->AsyncThreadHead = pCur->Next; - if (pCur == list->AsyncThreadTail) - list->AsyncThreadTail = pCur->Last; - if (pCur->Last) - ((running_thread_info *)(pCur->Last))->Next = pCur->Next; - if (pCur->Next) - ((running_thread_info *)(pCur->Next))->Last = pCur->Last; - /* Free malloc'd running_thread_info */ - free (pCur); - return; - } - } - - /* This is a serious progmatic error, since the thread - ** should be in that list! */ - XMLRPC_ASSERT_PTR_OK(0x0000); - - /* Unlock (); */ -} - -/* MRB-WARNING: Only call when you have successfully -** acquired the Lock/Unlock mutex! */ -void register_asynch_thread (running_thread_list *list, pthread_t *thread) -{ - running_thread_info* info = (running_thread_info *) malloc(sizeof(running_thread_info)); - - XMLRPC_ASSERT_PTR_OK(thread); - XMLRPC_ASSERT_PTR_OK(list); - - tdbg_printf("register_asynch_thread: &pthread_id = %08X *(%08X)\n", thread, *thread); - - info->_thread = *thread; - - /* Insertion */ - /* Lock (); */ - if (list->AsyncThreadHead == NULL) - { - list->AsyncThreadHead = list->AsyncThreadTail = info; - list->AsyncThreadTail->Next = list->AsyncThreadHead->Next = NULL; - list->AsyncThreadTail->Last = list->AsyncThreadHead->Last = NULL; - } - else - { - info->Last = list->AsyncThreadTail; - list->AsyncThreadTail->Next = info; - list->AsyncThreadTail = list->AsyncThreadTail->Next; - list->AsyncThreadTail->Next = NULL; - } - /* Unlock (); */ -} diff --git a/Utilities/cmxmlrpc/xmlrpc_transport.h b/Utilities/cmxmlrpc/xmlrpc_transport.h deleted file mode 100644 index 1a451669ab..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_transport.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright information is at the end of the file */ -#ifndef _XMLRPC_TRANSPORT_H_ -#define _XMLRPC_TRANSPORT_H_ 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(HAVE_PTHREADS) -# include "xmlrpc_pthreads.h" /* For threading helpers. */ -#endif - -struct call_info; - -struct clientTransport; - -/*========================================================================= -** Transport function type declarations. -**========================================================================= -*/ -typedef void (*transport_create)( - xmlrpc_env * const envP, - int const flags, - const char * const appname, - const char * const appversion, - struct clientTransport ** const handlePP); - -typedef void (*transport_destroy)( - struct clientTransport * const clientTransportP); - -typedef void (*transport_asynch_complete)( - struct call_info * const callInfoP, - xmlrpc_mem_block * const responseXmlP, - xmlrpc_env const env); - -typedef void (*transport_send_request)( - xmlrpc_env * const envP, - struct clientTransport * const clientTransportP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const xmlP, - transport_asynch_complete complete, - struct call_info * const callInfoP); - -typedef void (*transport_call)( - xmlrpc_env * const envP, - struct clientTransport * const clientTransportP, - xmlrpc_server_info * const serverP, - xmlrpc_mem_block * const xmlP, - struct call_info * const callInfoP, - xmlrpc_mem_block ** const responsePP); - -enum timeoutType {timeout_no, timeout_yes}; -typedef void (*transport_finish_asynch)( - struct clientTransport * const clientTransportP, - enum timeoutType const timeoutType, - timeout_t const timeout); - - -struct clientTransportOps { - - transport_create create; - transport_destroy destroy; - transport_send_request send_request; - transport_call call; - transport_finish_asynch finish_asynch; -}; - -/*========================================================================= -** Transport Helper Functions and declarations. -**========================================================================= -*/ -#if defined(HAVE_PTHREADS) -typedef struct _running_thread_info -{ - struct _running_thread_info * Next; - struct _running_thread_info * Last; - - pthread_t _thread; -} running_thread_info; - - -/* list of running Async callback functions. */ -typedef struct _running_thread_list -{ - running_thread_info * AsyncThreadHead; - running_thread_info * AsyncThreadTail; -} running_thread_list; - -/* MRB-WARNING: Only call when you have successfully -** acquired the Lock/Unlock mutex! */ -void register_asynch_thread (running_thread_list *list, pthread_t *thread); - -/* MRB-WARNING: Only call when you have successfully -** acquired the Lock/Unlock mutex! */ -void unregister_asynch_thread (running_thread_list *list, pthread_t *thread); -#endif - - -#ifdef __cplusplus -} -#endif - -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -#endif diff --git a/Utilities/cmxmlrpc/xmlrpc_utf8.c b/Utilities/cmxmlrpc/xmlrpc_utf8.c deleted file mode 100644 index 22223efffd..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_utf8.c +++ /dev/null @@ -1,372 +0,0 @@ -/* Copyright (C) 2001 by Eric Kidd. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -/*========================================================================= -** XML-RPC UTF-8 Utilities -**========================================================================= -** Routines for validating, encoding and decoding UTF-8 data. We try to -** be very, very strict about invalid UTF-8 data. -** -** All of the code in this file assumes that your machine represents -** wchar_t as a 16-bit (or wider) character containing UCS-2 data. If this -** assumption is incorrect, you may need to replace this file. -** -** For lots of information on Unicode and UTF-8 decoding, see: -** http://www.cl.cam.ac.uk/~mgk25/unicode.html -*/ - -#include "xmlrpc_config.h" - -#include "xmlrpc.h" - -#ifdef HAVE_UNICODE_WCHAR - -/*========================================================================= -** Tables and Constants -**========================================================================= -** We use a variety of tables and constants to help decode and validate -** UTF-8 data. -*/ - -/* The number of bytes in a UTF-8 sequence starting with the character used -** as the array index. A zero entry indicates an illegal initial byte. -** This table was generated using a Perl script and information from the -** UTF-8 standard. -** -** Fredrik Lundh's UTF-8 decoder Python 2.0 uses a similar table. But -** since Python 2.0 has the icky CNRI license, I regenerated this -** table from scratch and wrote my own decoder. */ -static unsigned char utf8_seq_length[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 -}; - -/* The minimum legal character value for a UTF-8 sequence of the given -** length. We have to check this to avoid accepting "overlong" UTF-8 -** sequences, which use more bytes than necessary to encode a given -** character. Such sequences are commonly used by evil people to bypass -** filters and security checks. This table is based on the UTF-8-test.txt -** file by Markus Kuhn . */ -static wchar_t utf8_min_char_for_length[4] = { - 0, /* Length 0: Not used (meaningless) */ - 0x0000, /* Length 1: Not used (special-cased) */ - 0x0080, /* Length 2 */ - 0x0800 /* Length 3 */ - -#if 0 - /* These are only useful on systems where wchar_t is 32-bits wide - ** and supports full UCS-4. */ - 0x00010000, /* Length 4 */ - 0x00200000, /* Length 5 */ - 0x04000000 /* Length 6 */ -#endif -}; - -/* This is the maximum legal 16-byte (UCS-2) character. Again, this -** information is based on UTF-8-test.txt. */ -#define UCS2_MAX_LEGAL_CHARACTER (0xFFFD) - -/* First and last UTF-16 surrogate characters. These are *not* legal UCS-2 -** characters--they're used to code for UCS-4 characters when using -** UTF-16. They should never appear in decoded UTF-8 data! Again, these -** could hypothetically be used to bypass security measures on some machines. -** Based on UTF-8-test.txt. */ -#define UTF16_FIRST_SURROGATE (0xD800) -#define UTF16_LAST_SURROGATE (0xDFFF) - -/* Is the character 'c' a UTF-8 continuation character? */ -#define IS_CONTINUATION(c) (((c) & 0xC0) == 0x80) - -/* Maximum number of bytes needed to encode a supported character. */ -#define MAX_ENCODED_BYTES (3) - - -/*========================================================================= -** decode_utf8 -**========================================================================= -** Internal routine which decodes (or validates) a UTF-8 string. -** To validate, set io_buff and out_buff_len to NULL. To decode, allocate -** a sufficiently large buffer, pass it as io_buff, and pass a pointer as -** as out_buff_len. The data will be written to the buffer, and the -** length to out_buff_len. -** -** We assume that wchar_t holds a single UCS-2 character in native-endian -** byte ordering. -*/ - -static void -decode_utf8(xmlrpc_env * const env, - const char * const utf8_data, - size_t const utf8_len, - wchar_t * const io_buff, - size_t * const out_buff_len) { - - size_t i, length, out_pos; - char init, con1, con2; - wchar_t wc; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(utf8_data); - XMLRPC_ASSERT((!io_buff && !out_buff_len) || - (io_buff && out_buff_len)); - - /* Suppress GCC warning about possibly undefined variable. */ - wc = 0; - - i = 0; - out_pos = 0; - while (i < utf8_len) { - init = utf8_data[i]; - if ((init & 0x80) == 0x00) { - /* Convert ASCII character to wide character. */ - wc = init; - i++; - } else { - /* Look up the length of this UTF-8 sequence. */ - length = utf8_seq_length[(unsigned char) init]; - - /* Check to make sure we have enough bytes to convert. */ - if (i + length > utf8_len) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "Truncated UTF-8 sequence"); - - /* Decode a multibyte UTF-8 sequence. */ - switch (length) { - case 0: - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "Invalid UTF-8 initial byte"); - - case 2: - /* 110xxxxx 10xxxxxx */ - con1 = utf8_data[i+1]; - if (!IS_CONTINUATION(con1)) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "UTF-8 sequence too short"); - wc = ((((wchar_t) (init & 0x1F)) << 6) | - (((wchar_t) (con1 & 0x3F)))); - break; - - case 3: - /* 1110xxxx 10xxxxxx 10xxxxxx */ - con1 = utf8_data[i+1]; - con2 = utf8_data[i+2]; - if (!IS_CONTINUATION(con1) || !IS_CONTINUATION(con2)) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "UTF-8 sequence too short"); - wc = ((((wchar_t) (init & 0x0F)) << 12) | - (((wchar_t) (con1 & 0x3F)) << 6) | - (((wchar_t) (con2 & 0x3F)))); - break; - - case 4: - /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - case 5: - /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - case 6: - /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "UCS-4 characters not supported"); - - default: - XMLRPC_ASSERT("Error in UTF-8 decoder tables"); - } - - /* Advance to the end of the sequence. */ - i += length; - - /* Check for illegal UCS-2 characters. */ - if (wc > UCS2_MAX_LEGAL_CHARACTER) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "UCS-2 characters > U+FFFD are illegal"); - - /* Check for UTF-16 surrogates. */ - if (UTF16_FIRST_SURROGATE <= wc && wc <= UTF16_LAST_SURROGATE) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "UTF-16 surrogates may not appear in UTF-8 data"); - - /* Check for overlong sequences. */ - if (wc < utf8_min_char_for_length[length]) - XMLRPC_FAIL(env, XMLRPC_INVALID_UTF8_ERROR, - "Overlong UTF-8 sequence not allowed"); - } - - /* If we have a buffer, write our character to it. */ - if (io_buff) { - io_buff[out_pos++] = wc; - } - } - - /* Record the number of characters we found. */ - if (out_buff_len) - *out_buff_len = out_pos; - - cleanup: - if (env->fault_occurred) { - if (out_buff_len) - *out_buff_len = 0; - } -} - - - -/*========================================================================= -** xmlrpc_validate_utf8 -**========================================================================= -** Make sure that a UTF-8 string is valid. -*/ - -void -xmlrpc_validate_utf8 (xmlrpc_env * const env, - const char * const utf8_data, - size_t const utf8_len) { - - decode_utf8(env, utf8_data, utf8_len, NULL, NULL); -} - - -/*========================================================================= -** xmlrpc_utf8_to_wcs -**========================================================================= -** Decode UTF-8 string to a "wide character string". This function -** returns an xmlrpc_mem_block with an element type of wchar_t. Don't -** try to intepret the block in a bytewise fashion--it won't work in -** any useful or portable fashion. -*/ - -xmlrpc_mem_block *xmlrpc_utf8_to_wcs (xmlrpc_env *env, - char *utf8_data, - size_t utf8_len) -{ - xmlrpc_mem_block *output; - size_t wcs_length; - - /* Allocate a memory block large enough to hold any possible output. - ** We assume that each byte of the input may decode to a whcar_t. */ - output = XMLRPC_TYPED_MEM_BLOCK_NEW(wchar_t, env, utf8_len); - XMLRPC_FAIL_IF_FAULT(env); - - /* Decode the UTF-8 data. */ - decode_utf8(env, utf8_data, utf8_len, - XMLRPC_TYPED_MEM_BLOCK_CONTENTS(wchar_t, output), - &wcs_length); - XMLRPC_FAIL_IF_FAULT(env); - - /* Make sure we didn't overrun our buffer. */ - XMLRPC_ASSERT(wcs_length <= utf8_len); - - /* Correct the length of the memory block. */ - XMLRPC_TYPED_MEM_BLOCK_RESIZE(wchar_t, env, output, wcs_length); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (env->fault_occurred) { - if (output) - xmlrpc_mem_block_free(output); - return NULL; - } - return output; -} - - -/*========================================================================= -** xmlrpc_utf8_to_wcs -**========================================================================= -** Encode a "wide character string" as UTF-8. -*/ - -xmlrpc_mem_block *xmlrpc_wcs_to_utf8 (xmlrpc_env *env, - wchar_t *wcs_data, - size_t wcs_len) -{ - size_t estimate, bytes_used, i; - xmlrpc_mem_block *output; - unsigned char *buffer; - wchar_t wc; - int cwc; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_PTR_OK(wcs_data); - - /* Allocate a memory block large enough to hold any possible output. - ** We assume that every wchar might encode to the maximum length. */ - estimate = wcs_len * MAX_ENCODED_BYTES; - output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, env, estimate); - XMLRPC_FAIL_IF_FAULT(env); - - /* Output our characters. */ - buffer = (unsigned char*) XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output); - bytes_used = 0; - for (i = 0; i < wcs_len; i++) { - wc = wcs_data[i]; - cwc = wc; - if (cwc <= 0x007F) { - buffer[bytes_used++] = wc & 0x7F; - } else if (cwc <= 0x07FF) { - /* 110xxxxx 10xxxxxx */ - buffer[bytes_used++] = 0xC0 | (wc >> 6); - buffer[bytes_used++] = 0x80 | (wc & 0x3F); - } else if (cwc <= 0xFFFF) { - /* 1110xxxx 10xxxxxx 10xxxxxx */ - buffer[bytes_used++] = 0xE0 | (wc >> 12); - buffer[bytes_used++] = 0x80 | ((wc >> 6) & 0x3F); - buffer[bytes_used++] = 0x80 | (wc & 0x3F); - } else { - XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, - "Don't know how to encode UCS-4 characters yet"); - } - } - - /* Make sure we didn't overrun our buffer. */ - XMLRPC_ASSERT(bytes_used <= estimate); - - /* Correct the length of the memory block. */ - XMLRPC_TYPED_MEM_BLOCK_RESIZE(char, env, output, bytes_used); - XMLRPC_FAIL_IF_FAULT(env); - - cleanup: - if (env->fault_occurred) { - if (output) - xmlrpc_mem_block_free(output); - return NULL; - } - return output; -} - -#endif /* HAVE_UNICODE_WCHAR */ diff --git a/Utilities/cmxmlrpc/xmlrpc_xmlparser.h b/Utilities/cmxmlrpc/xmlrpc_xmlparser.h deleted file mode 100644 index e575e8272f..0000000000 --- a/Utilities/cmxmlrpc/xmlrpc_xmlparser.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -** SUCH DAMAGE. */ - - -/*========================================================================= -** Abstract XML Parser Interface -**========================================================================= -** This file provides an abstract interface to the XML parser. For now, -** this interface is implemented by expat, but feel free to change it -** if necessary. -*/ - - -/*========================================================================= -** xml_element -**========================================================================= -** This data structure represents an XML element. We provide no more API -** than we'll need in xmlrpc_parse.c. -** -** The pointers returned by the various accessor methods belong to the -** xml_element structure. Do not free them, and do not use them after -** the xml_element has been destroyed. -*/ - -/* You'll need to finish defining struct _xml_element elsewhere. */ -typedef struct _xml_element xml_element; - -/* Destroy an xml_element. */ -void xml_element_free (xml_element *elem); - -/* Return a pointer to the element's name. Do not free this pointer! -** This pointer should point to standard ASCII or UTF-8 data. */ -char *xml_element_name (xml_element *elem); - -/* Return the xml_element's CDATA. Do not free this pointer! -** This pointer should point to standard ASCII or UTF-8 data. -** The implementation is allowed to concatenate all the CDATA in the -** element regardless of child elements. Alternatively, if there are -** any child elements, the implementation is allowed to dispose -** of whitespace characters. -** The value returned by xml_element_cdata should be '\0'-terminated -** (although it may contain other '\0' characters internally). -** xml_element_cdata_size should not include the final '\0'. */ -size_t xml_element_cdata_size (xml_element *elem); -char *xml_element_cdata (xml_element *elem); - -/* Return the xml_element's child elements. Do not free this pointer! */ -size_t xml_element_children_size (xml_element *elem); -xml_element **xml_element_children (xml_element *elem); - - -/*========================================================================= -** xml_parse -**========================================================================= -** Parse a chunk of XML data and return the top-level element. If this -** routine fails, it will return NULL and set up the env appropriately. -** You are responsible for calling xml_element_free on the returned pointer. -*/ - -xml_element *xml_parse (xmlrpc_env *env, const char *xml_data, int xml_len);