/* 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 #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)); goto cleanup; } while (0) #define XMLRPC_FAIL1(env,code,str,arg1) \ do { \ xmlrpc_env_set_fault_formatted((env),(code),(str),(arg1)); \ goto cleanup; \ } while (0) #define XMLRPC_FAIL2(env,code,str,arg1,arg2) \ do { \ xmlrpc_env_set_fault_formatted((env),(code),(str),(arg1),(arg2)); \ 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)); \ 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* env, size_t 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* env, xmlrpc_mem_block* block, size_t size); /* Append data to an existing xmlrpc_mem_block. */ void xmlrpc_mem_block_append (xmlrpc_env* env, xmlrpc_mem_block* block, void *data, size_t 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* value); /* Decrement the reference count of an xmlrpc_value. If there ** are no more references, free it. */ extern void xmlrpc_DECREF (xmlrpc_value* 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* env, xmlrpc_value* array, xmlrpc_value* value); void xmlrpc_array_read_item(xmlrpc_env * const envP, const xmlrpc_value * const arrayP, unsigned int const index, 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 index); /* 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 index, 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 * env, xmlrpc_value * strct, int index, xmlrpc_value ** out_keyval, xmlrpc_value ** 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