add xmlrpc-c 1.03.14 to in tree libs

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3772 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris
2006-12-21 03:57:49 +00:00
parent 6d9679b164
commit 3abb7730b2
338 changed files with 98032 additions and 2 deletions

View File

@@ -0,0 +1,751 @@
/*****************************************************************************
abyss.h
******************************************************************************
This file is the interface header for the Abyss HTTP server component of
XML-RPC For C/C++ (Xmlrpc-c).
The Abyss component of Xmlrpc-c is based on the independently developed
and distributed Abyss web server package from 2001.
Copyright information is at the end of the file.
****************************************************************************/
#ifndef _ABYSS_H_
#define _ABYSS_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef ABYSS_WIN32
#include "xmlrpc_config.h"
#else
#include <inttypes.h>
#endif
/*********************************************************************
** Paths and so on...
*********************************************************************/
#ifdef ABYSS_WIN32
#define DEFAULT_ROOT "c:\\abyss"
#define DEFAULT_DOCS DEFAULT_ROOT"\\htdocs"
#define DEFAULT_CONF_FILE DEFAULT_ROOT"\\conf\\abyss.conf"
#define DEFAULT_LOG_FILE DEFAULT_ROOT"\\log\\abyss.log"
#else
#ifdef __rtems__
#define DEFAULT_ROOT "/abyss"
#else
#define DEFAULT_ROOT "/usr/local/abyss"
#endif
#define DEFAULT_DOCS DEFAULT_ROOT"/htdocs"
#define DEFAULT_CONF_FILE DEFAULT_ROOT"/conf/abyss.conf"
#define DEFAULT_LOG_FILE DEFAULT_ROOT"/log/abyss.log"
#endif
/*********************************************************************
** Maximum numer of simultaneous connections
*********************************************************************/
#define MAX_CONN 16
/*********************************************************************
** Server Info Definitions
*********************************************************************/
#define SERVER_VERSION "0.3"
#define SERVER_HVERSION "ABYSS/0.3"
#define SERVER_HTML_INFO \
"<p><HR><b><i><a href=\"http:\057\057abyss.linuxave.net\">" \
"ABYSS Web Server</a></i></b> version "SERVER_VERSION"<br>" \
"&copy; <a href=\"mailto:mmoez@bigfoot.com\">Moez Mahfoudh</a> - 2000</p>"
#define SERVER_PLAIN_INFO \
CRLF "----------------------------------------" \
"----------------------------------------" \
CRLF "ABYSS Web Server version "SERVER_VERSION CRLF"(C) Moez Mahfoudh - 2000"
/*********************************************************************
** General purpose definitions
*********************************************************************/
#ifdef ABYSS_WIN32
#define strcasecmp(a,b) stricmp((a),(b))
#else
#define ioctlsocket(a,b,c) ioctl((a),(b),(c))
#endif /* ABYSS_WIN32 */
#ifndef NULL
#define NULL ((void *)0)
#endif /* NULL */
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifdef ABYSS_WIN32
#define LBR "\n"
#else
#define LBR "\n"
#endif /* ABYSS_WIN32 */
typedef int abyss_bool;
/*********************************************************************
** Buffer
*********************************************************************/
typedef struct
{
void *data;
uint32_t size;
uint32_t staticid;
} TBuffer;
abyss_bool BufferAlloc(TBuffer *buf,uint32_t memsize);
abyss_bool BufferRealloc(TBuffer *buf,uint32_t memsize);
void BufferFree(TBuffer *buf);
/*********************************************************************
** String
*********************************************************************/
typedef struct
{
TBuffer buffer;
uint32_t size;
} TString;
abyss_bool StringAlloc(TString *s);
abyss_bool StringConcat(TString *s,char *s2);
abyss_bool StringBlockConcat(TString *s,char *s2,char **ref);
void StringFree(TString *s);
char *StringData(TString *s);
/*********************************************************************
** List
*********************************************************************/
typedef struct {
void **item;
uint16_t size;
uint16_t maxsize;
abyss_bool autofree;
} TList;
void
ListInit(TList * const listP);
void
ListInitAutoFree(TList * const listP);
void
ListFree(TList * const listP);
void
ListFreeItems(TList * const listP);
abyss_bool
ListAdd(TList * const listP,
void * const str);
void
ListRemove(TList * const listP);
abyss_bool
ListAddFromString(TList * const listP,
char * const c);
abyss_bool
ListFindString(TList * const listP,
char * const str,
uint16_t * const indexP);
/*********************************************************************
** Table
*********************************************************************/
typedef struct
{
char *name,*value;
uint16_t hash;
} TTableItem;
typedef struct
{
TTableItem *item;
uint16_t size,maxsize;
} TTable;
void TableInit(TTable *t);
void TableFree(TTable *t);
abyss_bool TableAdd(TTable *t,char *name,char *value);
abyss_bool TableAddReplace(TTable *t,char *name,char *value);
abyss_bool TableFindIndex(TTable *t,char *name,uint16_t *index);
char *TableFind(TTable *t,char *name);
/*********************************************************************
** Thread
*********************************************************************/
#ifdef ABYSS_WIN32
#include <windows.h>
#define THREAD_ENTRYTYPE WINAPI
#else
#define THREAD_ENTRYTYPE
#include <pthread.h>
#endif /* ABYSS_WIN32 */
typedef uint32_t (THREAD_ENTRYTYPE *TThreadProc)(void *);
#ifdef ABYSS_WIN32
typedef HANDLE TThread;
#else
typedef pthread_t TThread;
typedef void* (*PTHREAD_START_ROUTINE)(void *);
#endif /* ABYSS_WIN32 */
abyss_bool ThreadCreate(TThread *t,TThreadProc func,void *arg);
abyss_bool ThreadRun(TThread *t);
abyss_bool ThreadStop(TThread *t);
abyss_bool ThreadKill(TThread *t);
void ThreadWait(uint32_t ms);
void ThreadExit( TThread *t, int ret_value );
void ThreadClose( TThread *t );
/*********************************************************************
** Mutex
*********************************************************************/
#ifdef ABYSS_WIN32
typedef HANDLE TMutex;
#else
typedef pthread_mutex_t TMutex;
#endif /* ABYSS_WIN32 */
abyss_bool MutexCreate(TMutex *m);
abyss_bool MutexLock(TMutex *m);
abyss_bool MutexUnlock(TMutex *m);
abyss_bool MutexTryLock(TMutex *m);
void MutexFree(TMutex *m);
/*********************************************************************
** Pool
*********************************************************************/
typedef struct _TPoolZone
{
char *pos,*maxpos;
struct _TPoolZone *next,*prev;
/* char data[0]; */
char data[1];
} TPoolZone;
typedef struct
{
TPoolZone *firstzone,*currentzone;
uint32_t zonesize;
TMutex mutex;
} TPool;
abyss_bool PoolCreate(TPool *p,uint32_t zonesize);
void PoolFree(TPool *p);
void *PoolAlloc(TPool *p,uint32_t size);
char *PoolStrdup(TPool *p,char *s);
/*********************************************************************
** Socket
*********************************************************************/
#ifdef ABYSS_WIN32
#include <winsock.h>
#else
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#endif /* ABYSS_WIN32 */
#define TIME_INFINITE 0xffffffff
#ifdef ABYSS_WIN32
typedef SOCKET TSocket;
#else
typedef uint32_t TSocket;
#endif /* ABYSS_WIN32 */
typedef struct in_addr TIPAddr;
#define IPB1(x) (((unsigned char *)(&x))[0])
#define IPB2(x) (((unsigned char *)(&x))[1])
#define IPB3(x) (((unsigned char *)(&x))[2])
#define IPB4(x) (((unsigned char *)(&x))[3])
abyss_bool SocketInit(void);
abyss_bool SocketCreate(TSocket *s);
abyss_bool SocketClose(TSocket *s);
int SocketWrite(TSocket *s, char *buffer, uint32_t len);
uint32_t SocketRead(TSocket *s, char *buffer, uint32_t len);
uint32_t SocketPeek(TSocket *s, char *buffer, uint32_t len);
abyss_bool SocketConnect(TSocket *s, TIPAddr *addr, uint16_t port);
abyss_bool SocketBind(TSocket *s, TIPAddr *addr, uint16_t port);
abyss_bool SocketListen(TSocket *s, uint32_t backlog);
abyss_bool SocketAccept(TSocket *s, TSocket *ns,TIPAddr *ip);
uint32_t SocketError(void);
uint32_t SocketWait(TSocket *s,abyss_bool rd,abyss_bool wr,uint32_t timems);
abyss_bool SocketBlocking(TSocket *s, abyss_bool b);
uint32_t SocketAvailableReadBytes(TSocket *s);
/*********************************************************************
** File
*********************************************************************/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#ifndef NAME_MAX
#define NAME_MAX 1024
#endif
#ifdef ABYSS_WIN32
#ifndef __BORLANDC__
#define O_APPEND _O_APPEND
#define O_CREAT _O_CREAT
#define O_EXCL _O_EXCL
#define O_RDONLY _O_RDONLY
#define O_RDWR _O_RDWR
#define O_TRUNC _O_TRUNC
#define O_WRONLY _O_WRONLY
#define O_TEXT _O_TEXT
#define O_BINARY _O_BINARY
#endif
#define A_HIDDEN _A_HIDDEN
#define A_NORMAL _A_NORMAL
#define A_RDONLY _A_RDONLY
#define A_SUBDIR _A_SUBDIR
#else
#define A_SUBDIR 1
#define O_BINARY 0
#define O_TEXT 0
#endif /* ABYSS_WIN32 */
#ifdef ABYSS_WIN32
#ifndef __BORLANDC__
typedef struct _stati64 TFileStat;
typedef struct _finddata_t TFileInfo;
typedef long TFileFind;
#else
typedef struct stat TFileStat;
typedef struct finddata_t
{
char name[NAME_MAX+1];
int attrib;
uint64_t size;
time_t time_write;
WIN32_FIND_DATA data;
} TFileInfo;
typedef HANDLE TFileFind;
#endif
#else
#include <unistd.h>
#include <dirent.h>
typedef struct stat TFileStat;
typedef struct finddata_t
{
char name[NAME_MAX+1];
int attrib;
uint64_t size;
time_t time_write;
} TFileInfo;
typedef struct
{
char path[NAME_MAX+1];
DIR *handle;
} TFileFind;
#endif
typedef int TFile;
abyss_bool FileOpen(TFile *f, const char *name,uint32_t attrib);
abyss_bool FileOpenCreate(TFile *f, const char *name, uint32_t attrib);
abyss_bool FileClose(TFile *f);
abyss_bool FileWrite(TFile *f, void *buffer, uint32_t len);
int32_t FileRead(TFile *f, void *buffer, uint32_t len);
abyss_bool FileSeek(TFile *f, uint64_t pos, uint32_t attrib);
uint64_t FileSize(TFile *f);
abyss_bool FileStat(char *filename,TFileStat *filestat);
abyss_bool FileFindFirst(TFileFind *filefind,char *path,TFileInfo *fileinfo);
abyss_bool FileFindNext(TFileFind *filefind,TFileInfo *fileinfo);
void FileFindClose(TFileFind *filefind);
/*********************************************************************
** Server (1/2)
*********************************************************************/
typedef struct _TServer
{
TSocket listensock;
TFile logfile;
TMutex logmutex;
char *name;
char *filespath;
uint16_t port;
uint32_t keepalivetimeout,keepalivemaxconn,timeout;
TList handlers;
TList defaultfilenames;
void *defaulthandler;
abyss_bool advertise;
#ifndef _WIN32
uid_t uid;
gid_t gid;
TFile pidfile;
#endif
} TServer;
/*********************************************************************
** Conn
*********************************************************************/
#define BUFFER_SIZE 4096
typedef struct _TConn
{
TServer *server;
uint32_t buffersize,bufferpos;
uint32_t inbytes,outbytes;
TSocket socket;
TIPAddr peerip;
abyss_bool hasOwnThread;
TThread thread;
abyss_bool connected;
abyss_bool inUse;
const char * trace;
void (*job)(struct _TConn *);
char buffer[BUFFER_SIZE];
} TConn;
TConn *ConnAlloc(void);
void ConnFree(TConn *c);
enum abyss_foreback {ABYSS_FOREGROUND, ABYSS_BACKGROUND};
abyss_bool ConnCreate(TConn *c, TSocket *s, void (*func)(TConn *));
abyss_bool ConnCreate2(TConn * const connectionP,
TServer * const serverP,
TSocket const connectedSocket,
TIPAddr const peerIpAddr,
void ( * func)(TConn *),
enum abyss_foreback const foregroundBackground);
abyss_bool ConnProcess(TConn *c);
abyss_bool ConnKill(TConn *c);
void ConnClose(TConn *c);
abyss_bool ConnWrite(TConn *c,void *buffer,uint32_t size);
abyss_bool ConnRead(TConn *c, uint32_t timems);
void ConnReadInit(TConn *c);
abyss_bool ConnReadLine(TConn *c,char **z,uint32_t timems);
abyss_bool ConnWriteFromFile(TConn *c,TFile *file,uint64_t start,uint64_t end,
void *buffer,uint32_t buffersize,uint32_t rate);
/*********************************************************************
** Range
*********************************************************************/
abyss_bool RangeDecode(char *str,uint64_t filesize,uint64_t *start,uint64_t *end);
/*********************************************************************
** Date
*********************************************************************/
#include <time.h>
typedef struct tm TDate;
abyss_bool DateToString(TDate *tm,char *s);
abyss_bool DateToLogString(TDate *tm,char *s);
abyss_bool DateDecode(char *s,TDate *tm);
int32_t DateCompare(TDate *d1,TDate *d2);
abyss_bool DateFromGMT(TDate *d,time_t t);
abyss_bool DateFromLocal(TDate *d,time_t t);
abyss_bool DateInit(void);
/*********************************************************************
** Base64
*********************************************************************/
void Base64Encode(char *s,char *d);
/*********************************************************************
** Session
*********************************************************************/
typedef enum
{
m_unknown,m_get,m_put,m_head,m_post,m_delete,m_trace,m_options
} TMethod;
typedef struct
{
TMethod method;
uint32_t nbfileds;
char *uri;
char *query;
char *host;
char *from;
char *useragent;
char *referer;
char *requestline;
char *user;
uint16_t port;
TList cookies;
TList ranges;
uint16_t status;
TString header;
abyss_bool keepalive,cankeepalive;
abyss_bool done;
TServer *server;
TConn *conn;
uint8_t versionminor,versionmajor;
TTable request_headers,response_headers;
TDate date;
abyss_bool chunkedwrite,chunkedwritemode;
} TSession;
/*********************************************************************
** Request
*********************************************************************/
#define CR '\r'
#define LF '\n'
#define CRLF "\r\n"
abyss_bool RequestValidURI(TSession *r);
abyss_bool RequestValidURIPath(TSession *r);
abyss_bool RequestUnescapeURI(TSession *r);
char *RequestHeaderValue(TSession *r,char *name);
abyss_bool RequestRead(TSession *r);
void RequestInit(TSession *r,TConn *c);
void RequestFree(TSession *r);
abyss_bool RequestAuth(TSession *r,char *credential,char *user,char *pass);
/*********************************************************************
** Response
*********************************************************************/
abyss_bool ResponseAddField(TSession *r,char *name,char *value);
void ResponseWrite(TSession *r);
abyss_bool ResponseChunked(TSession *s);
void ResponseStatus(TSession *r,uint16_t code);
void ResponseStatusErrno(TSession *r);
abyss_bool ResponseContentType(TSession *r,char *type);
abyss_bool ResponseContentLength(TSession *r,uint64_t len);
void ResponseError(TSession *r);
/*********************************************************************
** HTTP
*********************************************************************/
char *HTTPReasonByStatus(uint16_t status);
int32_t HTTPRead(TSession *s,char *buffer,uint32_t len);
abyss_bool HTTPWrite(TSession *s,char *buffer,uint32_t len);
abyss_bool HTTPWriteEnd(TSession *s);
/*********************************************************************
** Server (2/2)
*********************************************************************/
abyss_bool ServerCreate(TServer *srv,
const char *name,
uint16_t port,
const char *filespath,
const char *logfilename);
void ServerFree(TServer *srv);
void ServerInit(TServer *srv);
void ServerRun(TServer *srv);
void ServerRunOnce(TServer *srv);
void ServerRunOnce2(TServer * const srv,
enum abyss_foreback const foregroundBackground);
typedef abyss_bool (*URIHandler) (TSession *); /* deprecated */
struct URIHandler2;
typedef void (*initHandlerFn)(struct URIHandler2 *,
abyss_bool *);
typedef void (*termHandlerFn)(struct URIHandler2 *);
typedef void (*handleReq2Fn)(struct URIHandler2 *,
TSession *,
abyss_bool *);
typedef struct URIHandler2 {
initHandlerFn init;
termHandlerFn term;
handleReq2Fn handleReq2;
URIHandler handleReq1; /* deprecated */
void * userdata;
} URIHandler2;
void
ServerAddHandler2(TServer * const srvP,
URIHandler2 * const handlerP,
abyss_bool * const successP);
abyss_bool
ServerAddHandler(TServer * const srvP,
URIHandler const handler);
void
ServerDefaultHandler(TServer * const srvP,
URIHandler const handler);
abyss_bool LogOpen(TServer *srv, const char *filename);
void LogWrite(TServer *srv,char *c);
void LogClose(TServer *srv);
/*********************************************************************
** MIMEType
*********************************************************************/
void MIMETypeInit(void);
abyss_bool MIMETypeAdd(char *type,char *ext);
char *MIMETypeFromExt(char *ext);
char *MIMETypeFromFileName(char *filename);
char *MIMETypeGuessFromFile(char *filename);
/*********************************************************************
** Conf
*********************************************************************/
abyss_bool ConfReadMIMETypes(char *filename);
abyss_bool ConfReadServerFile(const char *filename,TServer *srv);
/*********************************************************************
** Trace
*********************************************************************/
void TraceMsg(char *fmt,...);
void TraceExit(char *fmt,...);
/*********************************************************************
** Session
*********************************************************************/
abyss_bool SessionLog(TSession *s);
#ifdef __cplusplus
}
#endif
/*****************************************************************************
** Here is the copyright notice from the Abyss web server project file from
** which this file is derived.
**
** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
** 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 /* _ABYSS_H_ */

View File

@@ -0,0 +1,886 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_H_INCLUDED
#define XMLRPC_H_INCLUDED
#include <stddef.h>
#include <stdarg.h>
#include <time.h>
#ifdef HAVE_UNICODE_WCHAR
#include <wchar.h>
#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 <int>; i.e. 32 bit */
typedef signed int xmlrpc_int32;
/* An integer of the type defined by XML-RPC <int4>; i.e. 32 bit */
typedef int xmlrpc_bool;
/* A boolean (of the type defined by XML-RPC <boolean>, but there's
really only one kind)
*/
typedef double xmlrpc_double;
/* A double precision floating point number as defined by
XML-RPC <float>. 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 long)(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
**=========================================================================
** Note that an assertion is _not_ a directive to check a condition and
** crash if it isn't true. It is an assertion that the condition _is_
** true. This assertion helps people to read the code. The program
** may also check the assertion as it runs, and if it conflicts with reality,
** recognize that the program is incorrect and abort it. In practice,
** it does this checking when the program was compiled without the NDEBUG
** macro defined.
*/
#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 <fault> elements. These contain
** <faultCode> and <faultString> 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,
...);
/* This one infers XMLRPC_INTERNAL_ERROR and has a shorter name.
So a call takes up less source code space.
*/
void
xmlrpc_faultf(xmlrpc_env * const envP,
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, const 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_NIL = 9,
XMLRPC_TYPE_DEAD = 0xDEAD
} xmlrpc_type;
/* These are *always* allocated on the heap. No exceptions. */
typedef struct _xmlrpc_value xmlrpc_value;
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);
xmlrpc_value *
xmlrpc_int_new(xmlrpc_env * const envP,
int const intValue);
void
xmlrpc_read_int(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
int * const intValueP);
xmlrpc_value *
xmlrpc_bool_new(xmlrpc_env * const envP,
xmlrpc_bool const boolValue);
void
xmlrpc_read_bool(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_bool * const boolValueP);
xmlrpc_value *
xmlrpc_double_new(xmlrpc_env * const envP,
double const doubleValue);
void
xmlrpc_read_double(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
xmlrpc_double * const doubleValueP);
xmlrpc_value *
xmlrpc_datetime_new_str(xmlrpc_env * const envP,
const char * const value);
xmlrpc_value *
xmlrpc_datetime_new_sec(xmlrpc_env * const envP,
time_t const value);
void
xmlrpc_read_datetime_str(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_datetime_sec(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
time_t * const timeValueP);
xmlrpc_value *
xmlrpc_string_new(xmlrpc_env * const envP,
const char * const stringValue);
xmlrpc_value *
xmlrpc_string_new_lp(xmlrpc_env * const envP,
size_t const length,
const char * const stringValue);
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,
size_t * const lengthP,
const char ** const stringValueP);
#ifdef HAVE_UNICODE_WCHAR
xmlrpc_value *
xmlrpc_string_w_new(xmlrpc_env * const envP,
const wchar_t * const stringValue);
xmlrpc_value *
xmlrpc_string_w_new_lp(xmlrpc_env * const envP,
size_t const length,
const wchar_t * const stringValue);
void
xmlrpc_read_string_w(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_lp(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
#endif
xmlrpc_value *
xmlrpc_base64_new(xmlrpc_env * const envP,
size_t const length,
const unsigned char * const value);
void
xmlrpc_read_base64(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const unsigned char ** const bytestringValueP);
void
xmlrpc_read_base64_size(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP);
xmlrpc_value *
xmlrpc_array_new(xmlrpc_env * const envP);
/* 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.
** Sets XMLRPC_TYPE_ERROR if 'array' is not an array. */
extern void
xmlrpc_array_append_item (xmlrpc_env * envP,
xmlrpc_value * arrayP,
xmlrpc_value * valueP);
void
xmlrpc_array_read_item(xmlrpc_env * const envP,
const xmlrpc_value * const arrayP,
unsigned int const index,
xmlrpc_value ** const valuePP);
/* Deprecated. Use xmlrpc_array_read_item() instead.
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 envP,
const xmlrpc_value * const arrayP,
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);
*/
void
xmlrpc_read_nil(xmlrpc_env * const envP,
xmlrpc_value * const valueP);
void
xmlrpc_read_cptr(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
void ** const ptrValueP);
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'.
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. Use xmlrpc_struct_read_member() instead.
*/
void
xmlrpc_struct_get_key_and_value(xmlrpc_env * env,
xmlrpc_value * strct,
int index,
xmlrpc_value ** out_keyval,
xmlrpc_value ** out_value);
xmlrpc_value *
xmlrpc_cptr_new(xmlrpc_env * const envP,
void * const value);
xmlrpc_value *
xmlrpc_nil_new(xmlrpc_env * const envP);
/* Build an xmlrpc_value from a format string. */
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);
void
xmlrpc_decompose_value(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
...);
void
xmlrpc_decompose_value_va(xmlrpc_env * const envP,
xmlrpc_value * const value,
const char * const format,
va_list args);
/* xmlrpc_parse_value... is the same as xmlrpc_decompose_value... except
that it doesn't do proper memory management -- it returns xmlrpc_value's
without incrementing the reference count and returns pointers to data
inside an xmlrpc_value structure.
These are deprecated. Use xmlrpc_decompose_value... instead.
*/
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);
/*=========================================================================
** 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 * const envP,
const char * const ascii_data,
size_t const 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
/* 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

View File

@@ -0,0 +1,312 @@
#ifndef XMLRPC_HPP_INCLUDED
#define XMLRPC_HPP_INCLUDED
#include <climits>
#include <cfloat>
#include <ctime>
#include <vector>
#include <map>
#include <string>
#include "xmlrpc-c/base.h"
namespace xmlrpc_c {
class value {
// This is a handle. You don't want to create a pointer to this;
// it is in fact a pointer itself.
public:
value();
// This creates a placeholder. It can't be used for anything, but
// holds memory. instantiate() can turn it into a real object.
value(xmlrpc_c::value const &value); // copy constructor
~value();
enum type_t {
TYPE_INT = 0,
TYPE_BOOLEAN = 1,
TYPE_DOUBLE = 2,
TYPE_DATETIME = 3,
TYPE_STRING = 4,
TYPE_BYTESTRING = 5,
TYPE_ARRAY = 6,
TYPE_STRUCT = 7,
TYPE_C_PTR = 8,
TYPE_NIL = 9,
TYPE_DEAD = 0xDEAD
};
type_t type() const;
xmlrpc_c::value&
operator=(xmlrpc_c::value const&);
// The following are not meant to be public to users, but just to
// other Xmlrpc-c library modules. If we ever go to a pure C++
// implementation, not based on C xmlrpc_value objects, this shouldn't
// be necessary.
void
appendToCArray(xmlrpc_value * const arrayP) const;
void
addToCStruct(xmlrpc_value * const structP,
std::string const key) const;
xmlrpc_value *
cValue() const;
value(xmlrpc_value * const valueP);
void
instantiate(xmlrpc_value * const valueP);
// Work only on a placeholder object created by the no-argument
// constructor.
xmlrpc_value * cValueP;
// NULL means this is merely a placeholder object.
};
class value_int : public value {
public:
value_int(int const cvalue);
value_int(xmlrpc_c::value const baseValue);
operator int() const;
};
class value_boolean : public value {
public:
value_boolean(bool const cvalue);
value_boolean(xmlrpc_c::value const baseValue);
operator bool() const;
};
class value_string : public value {
public:
value_string(std::string const& cvalue);
value_string(xmlrpc_c::value const baseValue);
operator std::string() const;
};
class value_double : public value {
public:
value_double(double const cvalue);
value_double(xmlrpc_c::value const baseValue);
operator double() const;
};
class value_datetime : public value {
public:
value_datetime(std::string const cvalue);
value_datetime(time_t const cvalue);
value_datetime(struct timeval const& cvalue);
value_datetime(struct timespec const& cvalue);
value_datetime(xmlrpc_c::value const baseValue);
operator time_t() const;
};
class value_bytestring : public value {
public:
value_bytestring(std::vector<unsigned char> const& cvalue);
value_bytestring(xmlrpc_c::value const baseValue);
// You can't cast to a vector because the compiler can't tell which
// constructor to use (complains about ambiguity). So we have this:
std::vector<unsigned char>
vectorUcharValue() const;
size_t
length() const;
};
class value_nil : public value {
public:
value_nil();
value_nil(xmlrpc_c::value const baseValue);
};
class value_struct : public value {
public:
value_struct(std::map<std::string, xmlrpc_c::value> const& cvalue);
value_struct(xmlrpc_c::value const baseValue);
operator std::map<std::string, xmlrpc_c::value>() const;
};
class value_array : public value {
public:
value_array(std::vector<xmlrpc_c::value> const& cvalue);
value_array(xmlrpc_c::value const baseValue);
std::vector<xmlrpc_c::value>
vectorValueValue() const;
size_t
size() const;
};
class fault {
/*----------------------------------------------------------------------------
This is an XML-RPC fault.
This object is not intended to be used to represent a fault in the
execution of XML-RPC client/server software -- just a fault in an
XML-RPC RPC as described by the XML-RPC spec.
There is no way to represent "no fault" with this object. The object is
meaningful only in the context of some fault.
-----------------------------------------------------------------------------*/
public:
enum code_t {
CODE_UNSPECIFIED = 0,
CODE_INTERNAL = -500,
CODE_TYPE = -501,
CODE_INDEX = -502,
CODE_PARSE = -503,
CODE_NETWORK = -504,
CODE_TIMEOUT = -505,
CODE_NO_SUCH_METHOD = -506,
CODE_REQUEST_REFUSED = -507,
CODE_INTROSPECTION_DISABLED = -508,
CODE_LIMIT_EXCEEDED = -509,
CODE_INVALID_UTF8 = -510
};
fault();
fault(std::string const _faultString,
xmlrpc_c::fault::code_t const _faultCode
= xmlrpc_c::fault::CODE_UNSPECIFIED
);
xmlrpc_c::fault::code_t getCode() const;
std::string getDescription() const;
private:
bool valid;
xmlrpc_c::fault::code_t code;
std::string description;
};
class rpcOutcome {
/*----------------------------------------------------------------------------
The outcome of a validly executed RPC -- either an XML-RPC fault
or an XML-RPC value of the result.
-----------------------------------------------------------------------------*/
public:
rpcOutcome();
rpcOutcome(xmlrpc_c::value const result);
rpcOutcome(xmlrpc_c::fault const fault);
bool succeeded() const;
xmlrpc_c::fault getFault() const;
xmlrpc_c::value getResult() const;
private:
bool valid;
// This is false in a placeholder variable -- i.e. an object you
// create with the no-argument constructor, which is waiting to be
// assigned a value. When false, nothing below is valid.
bool _succeeded;
xmlrpc_c::value result; // valid if 'succeeded'
xmlrpc_c::fault fault; // valid if not 'succeeded'
};
class paramList {
/*----------------------------------------------------------------------------
A parameter list of an XML-RPC call.
-----------------------------------------------------------------------------*/
public:
paramList(unsigned int const paramCount = 0);
void
add(xmlrpc_c::value const param);
unsigned int
size() const;
xmlrpc_c::value operator[](unsigned int const subscript) const;
int
getInt(unsigned int const paramNumber,
int const minimum = INT_MIN,
int const maximum = INT_MAX) const;
bool
getBoolean(unsigned int const paramNumber) const;
double
getDouble(unsigned int const paramNumber,
double const minimum = -DBL_MAX,
double const maximum = DBL_MAX) const;
enum timeConstraint {TC_ANY, TC_NO_PAST, TC_NO_FUTURE};
time_t
getDatetime_sec(unsigned int const paramNumber,
timeConstraint const constraint
= paramList::TC_ANY) const;
std::string
getString(unsigned int const paramNumber) const;
std::vector<unsigned char>
getBytestring(unsigned int const paramNumber) const;
std::vector<xmlrpc_c::value>
getArray(unsigned int const paramNumber,
unsigned int const minSize = 0,
unsigned int const maxSize = UINT_MAX) const;
std::map<std::string, xmlrpc_c::value>
getStruct(unsigned int const paramNumber) const;
void
getNil(unsigned int const paramNumber) const;
void
verifyEnd(unsigned int const paramNumber) const;
private:
std::vector<xmlrpc_c::value> paramVector;
};
} // namespace
#endif

View File

@@ -0,0 +1,190 @@
/*============================================================================
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_INCLUDED
#define XMLRPC_INT_H_INCLUDED
#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.
For a string, this is the characters of the string in UTF-8, plus
a NUL added to the end.
*/
xmlrpc_mem_block _block;
#ifdef HAVE_UNICODE_WCHAR
xmlrpc_mem_block *_wcs_block;
/* This is a copy of the string value in _block, but in UTF-16
instead of UTF-8. This member is not always present. If NULL,
it is not present.
We keep this copy for convenience. The value is totally
redundant with _block.
This member is always NULL when the data type is not string.
*/
#endif
};
#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)
typedef struct {
unsigned char key_hash;
xmlrpc_value *key;
xmlrpc_value *value;
} _struct_member;
void
xmlrpc_createXmlrpcValue(xmlrpc_env * const envP,
xmlrpc_value ** const valPP);
const char *
xmlrpc_typeName(xmlrpc_type const type);
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);
/*----------------------------------------------------------------------------
The following are for use by the legacy xmlrpc_parse_value(). They don't
do proper memory management, so they aren't appropriate for general use,
but there are old users that do xmlrpc_parse_value() and compensate for
the memory management, so we have to continue to offer this style of
memory management.
In particular, the functions that return xmlrpc_values don't increment
the reference count, and the functions that return strings don't allocate
new memory for them.
-----------------------------------------------------------------------------*/
void
xmlrpc_read_datetime_str_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
const char ** const stringValueP);
void
xmlrpc_read_string_lp_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const char ** const stringValueP);
#ifdef HAVE_UNICODE_WCHAR
void
xmlrpc_read_string_w_old(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
const wchar_t ** const stringValueP);
void
xmlrpc_read_string_w_lp_old(xmlrpc_env * const envP,
xmlrpc_value * const valueP,
size_t * const lengthP,
const wchar_t ** const stringValueP);
#endif
void
xmlrpc_read_base64_old(xmlrpc_env * const envP,
const xmlrpc_value * const valueP,
size_t * const lengthP,
const unsigned char ** const byteStringValueP);
/* 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

View File

@@ -0,0 +1,291 @@
/*============================================================================
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_INCLUDED
#define XMLRPC_CLIENT_H_INCLUDED
#include <xmlrpc-c/base.h>
#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_xportparms;
/* This is a "base class". The struct is never complete; you're
supposed to cast between struct xmlrpc_xportparms * and
"struct xmlrpc_..._xportparms *" in order to use it.
*/
struct xmlrpc_curl_xportparms {
const char * network_interface;
xmlrpc_bool no_ssl_verifypeer;
xmlrpc_bool no_ssl_verifyhost;
const char * user_agent;
};
#define XMLRPC_CXPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_curl_xportparms, mbrname)
/* XMLRPC_CXPSIZE(xyz) is analogous to XMLRPC_CPSIZE, below */
struct xmlrpc_wininet_xportparms {
int allowInvalidSSLCerts;
};
#define XMLRPC_WXPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_wininet_xportparms, mbrname)
/* XMLRPC_WXPSIZE(xyz) is analogous to XMLRPC_CPSIZE, below */
struct xmlrpc_clientparms {
const char * transport;
struct xmlrpc_xportparms * transportparmsP;
/* Cast a "struct ..._xportparms *" to fit here */
size_t transportparm_size;
};
#define XMLRPC_CPSIZE(mbrname) \
XMLRPC_STRUCTSIZE(struct xmlrpc_clientparms, 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,
const 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);
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 envP,
const char * const serverUrl,
const char * const methodName,
xmlrpc_value * const paramArrayP);
xmlrpc_value *
xmlrpc_client_call_server(xmlrpc_env * const envP,
const xmlrpc_server_info * const server,
const char * const method_name,
const char * const format,
...);
xmlrpc_value *
xmlrpc_client_call_server_params(
xmlrpc_env * const envP,
const xmlrpc_server_info * const serverP,
const char * const method_name,
xmlrpc_value * const paramArrayP);
void
xmlrpc_client_transport_call(
xmlrpc_env * const envP,
void * const reserved, /* for client handle */
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const callXmlP,
xmlrpc_mem_block ** const respXmlPP);
/*=========================================================================
** 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(unsigned long 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_ */

View File

@@ -0,0 +1,401 @@
#ifndef CLIENT_HPP_INCLUDED
#define CLIENT_HPP_INCLUDED
#include <string>
#include <xmlrpc-c/girerr.hpp>
#include <xmlrpc-c/girmem.hpp>
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/timeout.hpp>
#include <xmlrpc-c/client.h>
namespace xmlrpc_c {
class carriageParm {
/*----------------------------------------------------------------------------
The parameter to a client for an individual RPC. It tells specifics
of how to carry the call to the server and the response back. For
example, it may identify the server. It may identify communication
protocols to use. It may indicate permission and accounting
information.
This is a base class; the carriage parameter is specific to the
class of client. For example, an HTTP-based client would have a
URL and HTTP basic authentication info as parameter.
-----------------------------------------------------------------------------*/
protected:
virtual ~carriageParm();
carriageParm();
};
class clientTransactionPtr;
class clientTransaction : public girmem::autoObject {
friend class clientTransactionPtr;
public:
virtual void
finish(xmlrpc_c::rpcOutcome const& outcome) = 0;
virtual void
finishErr(girerr::error const& error) = 0;
protected:
clientTransaction();
};
class clientTransactionPtr : public girmem::autoObjectPtr {
public:
clientTransactionPtr();
virtual ~clientTransactionPtr();
virtual xmlrpc_c::clientTransaction *
operator->() const;
};
class client {
/*----------------------------------------------------------------------------
A generic client -- a means of performing an RPC. This is so generic
that it can be used for clients that are not XML-RPC.
This is a base class. Derived classes define things such as that
XML and HTTP get used to perform the RPC.
-----------------------------------------------------------------------------*/
public:
virtual ~client();
virtual void
call(carriageParm * const carriageParmP,
std::string const methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::rpcOutcome * const outcomeP) = 0;
virtual void
start(xmlrpc_c::carriageParm * const carriageParmP,
std::string const methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::clientTransactionPtr const& tranP);
};
class connection {
/*----------------------------------------------------------------------------
A nexus of a particular client and a particular server, along with
carriage parameters for performing RPCs between the two.
This is a minor convenience for client programs that always talk to
the same server the same way.
Use this as a parameter to rpc.call().
-----------------------------------------------------------------------------*/
public:
connection(xmlrpc_c::client * const clientP,
xmlrpc_c::carriageParm * const carriageParmP);
~connection();
xmlrpc_c::client * clientP;
xmlrpc_c::carriageParm * carriageParmP;
};
class carriageParm_http0 : public carriageParm {
public:
carriageParm_http0(std::string const serverUrl);
~carriageParm_http0();
void
setBasicAuth(std::string const userid,
std::string const password);
xmlrpc_server_info * c_serverInfoP;
protected:
// Only a derived class is allowed to create an object with no
// server URL, and the derived class expected to follow it up
// with an instantiate() to establish the server URL.
carriageParm_http0();
void
instantiate(std::string const serverUrl);
};
class carriageParm_curl0 : public xmlrpc_c::carriageParm_http0 {
public:
carriageParm_curl0(std::string const serverUrl);
};
class carriageParm_libwww0 : public xmlrpc_c::carriageParm_http0 {
public:
carriageParm_libwww0(std::string const serverUrl);
};
class carriageParm_wininet0 : public xmlrpc_c::carriageParm_http0 {
public:
carriageParm_wininet0(std::string const serverUrl);
};
class xmlTransactionPtr;
class xmlTransaction : public girmem::autoObject {
friend class xmlTransactionPtr;
public:
virtual void
finish(std::string const& responseXml) const;
virtual void
finishErr(girerr::error const& error) const;
protected:
xmlTransaction();
};
class xmlTransactionPtr : public girmem::autoObjectPtr {
public:
xmlTransactionPtr();
xmlrpc_c::xmlTransaction *
operator->() const;
};
class clientXmlTransport {
/*----------------------------------------------------------------------------
An object which transports XML to and from an XML-RPC server for an
XML-RPC client.
This is a base class. Derived classes define methods to perform the
transportation in particular ways.
-----------------------------------------------------------------------------*/
public:
virtual ~clientXmlTransport();
virtual void
call(xmlrpc_c::carriageParm * const carriageParmP,
std::string const& callXml,
std::string * const responseXmlP) = 0;
virtual void
start(xmlrpc_c::carriageParm * const carriageParmP,
std::string const& callXml,
xmlrpc_c::xmlTransactionPtr const& xmlTranP);
virtual void
finishAsync(xmlrpc_c::timeout const timeout);
static void
asyncComplete(
struct xmlrpc_call_info * const callInfoP,
xmlrpc_mem_block * const responseXmlMP,
xmlrpc_env const transportEnv);
};
class clientXmlTransport_http : public xmlrpc_c::clientXmlTransport {
/*----------------------------------------------------------------------------
A base class for client XML transports that use the simple, classic
C HTTP transports.
-----------------------------------------------------------------------------*/
public:
virtual ~clientXmlTransport_http();
void
call(xmlrpc_c::carriageParm * const carriageParmP,
std::string const& callXml,
std::string * const responseXmlP);
void
start(xmlrpc_c::carriageParm * const carriageParmP,
std::string const& callXml,
xmlrpc_c::xmlTransactionPtr const& xmlTranP);
virtual void
finishAsync(xmlrpc_c::timeout const timeout);
protected:
clientXmlTransport_http() {} // ensure no one can create
struct xmlrpc_client_transport * c_transportP;
const struct xmlrpc_client_transport_ops * c_transportOpsP;
};
class clientXmlTransport_curl : public xmlrpc_c::clientXmlTransport_http {
public:
clientXmlTransport_curl(std::string const networkInterface = "",
bool const noSslVerifyPeer = false,
bool const noSslVerifyHost = false,
std::string const userAgent = "");
~clientXmlTransport_curl();
};
class clientXmlTransport_libwww : public xmlrpc_c::clientXmlTransport_http {
public:
clientXmlTransport_libwww(std::string const appname = "",
std::string const appversion = "");
~clientXmlTransport_libwww();
};
class clientXmlTransport_wininet : public xmlrpc_c::clientXmlTransport_http {
public:
clientXmlTransport_wininet(bool const allowInvalidSslCerts = false);
~clientXmlTransport_wininet();
};
class client_xml : public xmlrpc_c::client {
/*----------------------------------------------------------------------------
A client that uses XML-RPC XML in the RPC. This class does not define
how the XML gets transported, though (i.e. does not require HTTP).
-----------------------------------------------------------------------------*/
public:
client_xml(xmlrpc_c::clientXmlTransport * const transportP);
void
call(carriageParm * const carriageParmP,
std::string const methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::rpcOutcome * const outcomeP);
void
start(xmlrpc_c::carriageParm * const carriageParmP,
std::string const methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::clientTransactionPtr const& tranP);
void
finishAsync(xmlrpc_c::timeout const timeout);
private:
xmlrpc_c::clientXmlTransport * transportP;
};
class xmlTransaction_client : public xmlrpc_c::xmlTransaction {
public:
xmlTransaction_client(xmlrpc_c::clientTransactionPtr const& tranP);
void
finish(std::string const& responseXml) const;
void
finishErr(girerr::error const& error) const;
private:
xmlrpc_c::clientTransactionPtr const tranP;
};
class xmlTransaction_clientPtr : public xmlTransactionPtr {
public:
xmlTransaction_clientPtr();
xmlTransaction_clientPtr(xmlrpc_c::clientTransactionPtr const& tranP);
xmlrpc_c::xmlTransaction_client *
operator->() const;
};
class rpcPtr;
class rpc : public clientTransaction {
/*----------------------------------------------------------------------------
An RPC. An RPC consists of method name, parameters, and result. It
does not specify in any way how the method name and parameters get
turned into a result. It does not presume XML or HTTP.
You don't create an object of this class directly. All references to
an rpc object should be by an rpcPtr object. Create a new RPC by
creating a new rpcPtr. Accordingly, our constructors and destructors
are protected, but available to our friend class rpcPtr.
In order to do asynchronous RPCs, you normally have to create a derived
class that defines a useful notifyComplete(). If you do that, you'll
want to make sure the derived class objects get accessed only via rpcPtrs
as well.
-----------------------------------------------------------------------------*/
friend class xmlrpc_c::rpcPtr;
public:
void
call(xmlrpc_c::client * const clientP,
xmlrpc_c::carriageParm * const carriageParmP);
void
call(xmlrpc_c::connection const& connection);
void
start(xmlrpc_c::client * const clientP,
xmlrpc_c::carriageParm * const carriageParmP);
void
start(xmlrpc_c::connection const& connection);
void
finish(xmlrpc_c::rpcOutcome const& outcome);
void
finishErr(girerr::error const& error);
virtual void
notifyComplete();
bool
isFinished() const;
bool
isSuccessful() const;
xmlrpc_c::value
getResult() const;
xmlrpc_c::fault
getFault() const;
protected:
rpc(std::string const methodName,
xmlrpc_c::paramList const& paramList);
virtual ~rpc();
private:
enum state {
STATE_UNFINISHED, // RPC is running or not started yet
STATE_ERROR, // We couldn't execute the RPC
STATE_FAILED, // RPC executed successfully, but failed per XML-RPC
STATE_SUCCEEDED // RPC is done, no exception
};
enum state state;
girerr::error * errorP; // Defined only in STATE_ERROR
xmlrpc_c::rpcOutcome outcome;
// Defined only in STATE_FAILED and STATE_SUCCEEDED
std::string methodName;
xmlrpc_c::paramList paramList;
};
class rpcPtr : public clientTransactionPtr {
public:
rpcPtr();
rpcPtr(xmlrpc_c::rpc * const rpcP);
rpcPtr(std::string const methodName,
xmlrpc_c::paramList const& paramList);
xmlrpc_c::rpc *
operator->() const;
};
} // namespace
#endif

View File

@@ -0,0 +1,102 @@
/*============================================================================
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_INCLUDED
#define XMLRPC_CLIENT_INT_H_INCLUDED
#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-c/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, xmlrpc_timeout 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 (xmlrpc_timeout 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

View File

@@ -0,0 +1,47 @@
#ifndef CLIENT_SIMPLE_HPP_INCLUDED
#define CLIENT_SIMPLE_HPP_INCLUDED
#include <string>
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/client.hpp>
namespace xmlrpc_c {
class clientSimple {
public:
clientSimple();
~clientSimple();
void
call(std::string const serverUrl,
std::string const methodName,
xmlrpc_c::value * const resultP);
void
call(std::string const serverUrl,
std::string const methodName,
std::string const format,
xmlrpc_c::value * const resultP,
...);
void
call(std::string const serverUrl,
std::string const methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const resultP);
private:
xmlrpc_c::client * clientP;
xmlrpc_c::clientXmlTransport * transportP;
};
} // namespace
#endif

View File

@@ -0,0 +1,26 @@
#ifndef GIRERR_HPP_INCLUDED
#define GIRERR_HPP_INCLUDED
#include <string>
#include <exception>
#define HAVE_GIRERR_ERROR
namespace girerr {
class error : public std::exception {
public:
error(std::string const& what_arg) : _what(what_arg) {}
~error() throw() {}
virtual const char *
what() const throw() { return this->_what.c_str(); };
private:
std::string _what;
};
} // namespace
#endif

View File

@@ -0,0 +1,68 @@
#ifndef GIRMEM_HPP_INCLUDED
#define GIRMEM_HPP_INCLUDED
/* The following pthread crap mirrors what is in pthreadx.h, which is
what girmem.cpp uses to declare the lock interface. We can't simply
include pthreadx.h here, because it's an internal Xmlrpc-c header file,
and this is an external one.
This is a stopgap measure until we do something cleaner, such as expose
pthreadx.h as an external interface (class girlock, maybe?) or create
a lock class with virtual methods.
The problem we're solving is that class autoObject contains
a pthread_mutex_t member, and on Windows, there's no such type.
*/
#ifndef WIN32
# include <pthread.h>
typedef pthread_mutex_t girmem_lock;
#else
typedef CRITICAL_SECTION girmem_lock;
#endif
namespace girmem {
class autoObjectPtr;
class autoObject {
friend class autoObjectPtr;
public:
void incref();
void decref(bool * const unreferencedP);
protected:
autoObject();
virtual ~autoObject();
private:
girmem_lock refcountLock;
unsigned int refcount;
};
class autoObjectPtr {
public:
autoObjectPtr();
autoObjectPtr(girmem::autoObject * objectP);
autoObjectPtr(girmem::autoObjectPtr const& autoObjectPtr);
~autoObjectPtr();
void
instantiate(girmem::autoObject * const objectP);
autoObjectPtr
operator=(girmem::autoObjectPtr const& objectPtr);
girmem::autoObject *
operator->() const;
protected:
girmem::autoObject * objectP;
};
} // namespace
#endif

View File

@@ -0,0 +1,418 @@
// -*- C++ -*- <-- an Emacs control
// Copyright information is at the bottom of the file.
//=========================================================================
// XML-RPC C++ API
//=========================================================================
#ifndef XMLRPCCPP_H_INCLUDED
#define XMLRPCCPP_H_INCLUDED
// There used to be a "using namespace std" here and some confusing old
// comments about it having something to do with what header file you
// include to get string functions.
//
// "using namespace std" was under "#if defined(__GNUC__) && (__GNUC__ >= 3)"
// until December 2003, and then unconditional until Release 1.1 (March 2005).
// Older GNU Compilers apparently imply namespace std, so they don't need it.
//
// But "using namespace std" is a bad idea. This is an interface header
// file, and we don't want to suck all of namespace std into the user's
// namespace just because he's using Xmlrpc-c. So we took it out.
// We refer to std names like std::string.
// -Bryan 2005.03.12.
#include <string>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <xmlrpc-c/server.h>
//=========================================================================
// XmlRpcFault
//=========================================================================
// A C++ exception class representing an XML-RPC fault.
class XmlRpcFault {
private:
xmlrpc_env mFault;
XmlRpcFault& operator= (XmlRpcFault const& f)
{ if (true || f.getFaultCode()) abort(); return (XmlRpcFault&) f; }
public:
XmlRpcFault (const XmlRpcFault &fault);
XmlRpcFault (const int faultCode, const std::string faultString);
XmlRpcFault (const xmlrpc_env *env);
~XmlRpcFault (void);
int getFaultCode (void) const;
std::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= (XmlRpcEnv const& e)
{ if (true || e.faultOccurred()) abort(); return (XmlRpcEnv&) e;}
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.
*/
std::string getFaultString() const { return mEnv.fault_string; };
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 holds 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 std::string& dateTime);
static XmlRpcValue makeString (const std::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;
std::string getRawDateTime (void) const;
std::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 std::string& key) const;
XmlRpcValue structGetValue (const std::string& key) const;
void structSetValue (const std::string& key,
const XmlRpcValue& value);
void structGetKeyAndValue (const int index,
std::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:
std::string mServerUrl;
public:
static void Initialize (std::string appname, std::string appversion);
static void Terminate (void);
XmlRpcClient (const std::string& server_url) : mServerUrl(server_url) {}
~XmlRpcClient (void) {}
XmlRpcClient (const XmlRpcClient& client);
XmlRpcClient& operator= (const XmlRpcClient& client);
XmlRpcValue call (std::string method_name, XmlRpcValue param_array);
void call_asynch (std::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(std::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 (std::string appname,
std::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 (std::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 std::string& body) const;
public:
XmlRpcGenSrv (int flags);
~XmlRpcGenSrv (void);
xmlrpc_registry* getRegistry (void) const;
XmlRpcGenSrv& addMethod (const std::string& name,
xmlrpc_method method,
void *data);
XmlRpcGenSrv& addMethod (const std::string& name,
xmlrpc_method method,
void* data,
const std::string& signature,
const std::string& help);
std::string handle (const std::string& body) const;
};
inline XmlRpcGenSrv::XmlRpcGenSrv (int) {
XmlRpcEnv env;
mRegistry = xmlrpc_registry_new (env);
env.throwIfFaultOccurred();
}
inline XmlRpcGenSrv::~XmlRpcGenSrv (void) {
xmlrpc_registry_free (mRegistry);
}
inline xmlrpc_registry* XmlRpcGenSrv::getRegistry () const {
return mRegistry;
}
// 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_ */

View File

@@ -0,0 +1,2 @@
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/server.h>

View File

@@ -0,0 +1,167 @@
#ifndef REGISTRY_HPP_INCLUDED
#define REGISTRY_HPP_INCLUDED
#include <string>
#include <vector>
#include <list>
#include <xmlrpc-c/server.h>
#include <xmlrpc-c/girmem.hpp>
#include <xmlrpc-c/base.hpp>
namespace xmlrpc_c {
class method : public girmem::autoObject {
/*----------------------------------------------------------------------------
An XML-RPC method.
This base class is abstract. You can't create an object in it.
Define a useful method with this as a base class, with an
execute() method.
-----------------------------------------------------------------------------*/
public:
method();
virtual ~method();
virtual void
execute(xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const resultP) = 0;
std::string signature() const { return _signature; };
std::string help() const { return _help; };
// self() is a strange concession to the fact that we interface with
// C code. C code needs a regular pointer to this method, but our
// C++ interface carefully prevents one from making such a pointer,
// since it would be an uncounted reference. So users of self() must
// make sure that the reference it returns is always subordinate to a
// methodPtr reference.
xmlrpc_c::method * self();
protected:
std::string _signature;
std::string _help;
};
/* Example of a specific method class:
class sample_add : public xmlrpc_c::method {
public:
sample_add() {
this->_signature = "ii";
this->_help = "This method adds two integers together";
}
void
execute(xmlrpc_c::param_list const paramList,
const xmlrpc_c::value * const retvalP) {
int const addend(paramList.getInt(0));
int const adder(paramList.getInt(1));
*retvalP = xmlrpc_c::value(addend, adder);
}
};
Example of creating such a method:
methodPtr const sampleAddMethodP(new sample_add);
You pass around, copy, etc. the handle sampleAddMethodP and when
the last copy of the handle is gone, the sample_add object itself
gets deleted.
*/
class methodPtr : public girmem::autoObjectPtr {
public:
methodPtr(xmlrpc_c::method * const methodP);
xmlrpc_c::method *
operator->() const;
};
class defaultMethod : public girmem::autoObject {
public:
virtual ~defaultMethod();
virtual void
execute(std::string const& methodName,
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const resultP) = 0;
xmlrpc_c::defaultMethod * self(); // analogous to 'method' class
};
class defaultMethodPtr : public girmem::autoObjectPtr {
public:
defaultMethodPtr();
defaultMethodPtr(xmlrpc_c::defaultMethod * const methodP);
xmlrpc_c::defaultMethod *
operator->() const;
};
class registry {
/*----------------------------------------------------------------------------
An Xmlrpc-c server method registry. An Xmlrpc-c server transport
(e.g. an HTTP server) uses this object to process an incoming
Xmlrpc-c call.
-----------------------------------------------------------------------------*/
public:
registry();
~registry();
void
addMethod(std::string const name,
xmlrpc_c::methodPtr const methodP);
void
setDefaultMethod(xmlrpc_c::defaultMethodPtr const methodP);
void
disableIntrospection();
void
processCall(std::string const& body,
std::string * const responseP) const;
xmlrpc_registry *
c_registry() const;
/* This is meant to be private except to other objects in the
Xmlrpc-c library.
*/
private:
xmlrpc_registry * c_registryP;
/* Pointer to the C registry object we use to implement this
object.
*/
std::list<xmlrpc_c::methodPtr> methodList;
/* This is a list of all the method objects (actually, pointers
to them). But since the real registry is the C registry object,
all this list is for is to maintain references to the objects
to which the C registry points so that they continue to exist.
*/
xmlrpc_c::defaultMethodPtr defaultMethodP;
/* The real identifier of the default method is the C registry
object; this member exists only to maintain a reference to the
object to which the C registry points so that it will continue
to exist.
*/
};
} // namespace
#endif

View File

@@ -0,0 +1,179 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_SERVER_H_INCLUDED
#define XMLRPC_SERVER_H_INCLUDED
#include <xmlrpc-c/base.h>
#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 <methodCall>,
** find the appropriate method, call it, serialize the response, and
** return it as an xmlrpc_mem_block. Most errors will be serialized
** as <fault> 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
/* 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

View File

@@ -0,0 +1,204 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_SERVER_ABYSS_H_INCLUDED
#define XMLRPC_SERVER_ABYSS_H_INCLUDED
#include "xmlrpc-c/server.h"
#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;
/* NULL to use preferred proper API-level interface */
xmlrpc_registry * registryP;
/* runfirstFn and runfirst_arg are meaningless when
config_file_name is NULL
*/
runfirstFn runfirst;
void * runfirst_arg;
unsigned int port_number;
const char * log_file_name;
unsigned int keepalive_timeout;
unsigned int keepalive_max_conn;
unsigned int timeout;
xmlrpc_bool dont_advertise;
} 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);
void
xmlrpc_server_abyss_set_handler(xmlrpc_env * const envP,
struct _TServer * const srvP,
const char * const filename,
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 */
/* 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

View File

@@ -0,0 +1,47 @@
#ifndef SERVER_ABYSS_HPP_INCLUDED
#define SERVER_ABYSS_HPP_INCLUDED
#include "xmlrpc-c/base.hpp"
#include "abyss.h"
namespace xmlrpc_c {
class serverAbyss {
public:
serverAbyss(
xmlrpc_c::registry const& registry,
unsigned int const portNumber = 8080,
std::string const& logFileName = "",
unsigned int const keepaliveTimeout = 0,
unsigned int const keepaliveMaxConn = 0,
unsigned int const timeout = 0,
bool const dontAdvertise = false
);
~serverAbyss();
void run();
private:
// We rely on the creator to keep the registry object around as
// long as the server object is, so that this pointer is valid.
// We need to use some kind of automatic handle instead.
const xmlrpc_c::registry * registryP;
std::string configFileName;
std::string logFileName;
unsigned int portNumber;
unsigned int keepaliveTimeout;
unsigned int keepaliveMaxConn;
unsigned int timeout;
bool dontAdvertise;
};
void
server_abyss_set_handlers(TServer * const srvP,
xmlrpc_c::registry const& registry);
} // namespace
#endif

View File

@@ -0,0 +1,49 @@
/* Interface header file for libxmlrpc_server_cgi.
By Bryan Henderson, 05.04.27. Contributed to the public domain.
*/
#ifndef XMLRPC_CGI_H_INCLUDED
#define XMLRPC_CGI_H_INCLUDED
#include <xmlrpc-c/server.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void
xmlrpc_server_cgi_process_call(xmlrpc_registry * const registryP);
#define XMLRPC_CGI_NO_FLAGS (0)
extern void
xmlrpc_cgi_init (int flags);
extern xmlrpc_registry *
xmlrpc_cgi_registry (void);
void
xmlrpc_cgi_add_method(const char * const method_name,
xmlrpc_method const method,
void * const user_data);
void
xmlrpc_cgi_add_method_w_doc(const char * const method_name,
xmlrpc_method const method,
void * const user_data,
const char * const signature,
const char * const help);
extern void
xmlrpc_cgi_process_call (void);
extern void
xmlrpc_cgi_cleanup (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -0,0 +1,95 @@
/* Copyright (C) 2005 by Steven A. Bone, sbone@pobox.com. 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. */
/* COMPILATION NOTE:
Note that the Platform SDK headers and
link libraries for Windows XP SP2 or newer are required to compile
xmlrpc-c for this module. If you are not using this server, it is
safe to exclude the xmlrpc_server_w32httpsys.c file from the xmlrpc
project and these dependencies will not be required. You can get the
latest platform SDK at
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
Be sure after installation to choose the program to "register the PSDK
directories with Visual Studio" so the newer headers are found.
*/
#ifndef _XMLRPC_SERVER_HTTPSYS_H_
#define _XMLRPC_SERVER_HTTPSYS_H_ 1
#include "transport_config.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*=========================================================================
** XML-RPC Server (based on HTTP.SYS)
**=========================================================================
** A simple XML-RPC server based on the "built-in" Windows web server,
** HTTP.SYS. This is provided by Microsoft in Windows XP SP2 and
** Windows Server 2003. If errors occur during server setup, the server
** will exit. In general, if you want to use this API, you do not really
** need to be familiar with the HTTP.SYS API.
*/
typedef void (*authorization_function)(
xmlrpc_env * envP,
char * userid,
char * password);
typedef struct {
xmlrpc_registry * registryP;
unsigned int portNum;
unsigned int useSSL;
/* useSSL, 0 = no SSL, 1 = use SSL */
unsigned int logLevel;
/* logLevel, 0 = none, 1 = file, 2 = file+OutputDebugString() */
const char * logFile;
/* logFile, NULL or filename */
authorization_function authfn;
} xmlrpc_server_httpsys_parms;
#define XMLRPC_HSSIZE(MBRNAME) \
XMLRPC_STRUCTSIZE(xmlrpc_server_httpsys_parms, MBRNAME)
/* XMLRPC_HSSIZE(xyz) is the minimum size a struct xmlrpc_server_httpsys_parms
must be to include the 'xyz' member. This is essential for 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_httpsys(
xmlrpc_env * const envP,
const xmlrpc_server_httpsys_parms * const parmsP,
unsigned int const parm_size
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -0,0 +1,19 @@
#ifndef XMLRPC_TIMEOUT_H_INCLUDED
#define XMLRPC_TIMEOUT_H_INCLUDED
namespace xmlrpc_c {
struct timeout {
timeout() : finite(false) {}
timeout(unsigned int const duration) : duration(duration) {}
bool finite;
unsigned int duration;
};
} // namespace
#endif

View File

@@ -0,0 +1,75 @@
/* Copyright information is at the end of the file */
#ifndef XMLRPC_TRANSPORT_H_INCLUDED
#define XMLRPC_TRANSPORT_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "xmlrpc-c/base.h"
struct xmlrpc_call_info;
struct xmlrpc_client_transport;
/*=========================================================================
** Transport function type declarations.
**=========================================================================
*/
typedef void (*xmlrpc_transport_create)(
xmlrpc_env * const envP,
int const flags,
const char * const appname,
const char * const appversion,
const struct xmlrpc_xportparms * const transportparmsP,
size_t const transportparm_size,
struct xmlrpc_client_transport ** const handlePP);
typedef void (*xmlrpc_transport_destroy)(
struct xmlrpc_client_transport * const clientTransportP);
typedef void (*xmlrpc_transport_asynch_complete)(
struct xmlrpc_call_info * const callInfoP,
xmlrpc_mem_block * const responseXmlP,
xmlrpc_env const env);
typedef void (*xmlrpc_transport_send_request)(
xmlrpc_env * const envP,
struct xmlrpc_client_transport * const clientTransportP,
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const xmlP,
xmlrpc_transport_asynch_complete complete,
struct xmlrpc_call_info * const callInfoP);
typedef void (*xmlrpc_transport_call)(
xmlrpc_env * const envP,
struct xmlrpc_client_transport * const clientTransportP,
const xmlrpc_server_info * const serverP,
xmlrpc_mem_block * const xmlP,
xmlrpc_mem_block ** const responsePP);
typedef enum {timeout_no, timeout_yes} xmlrpc_timeoutType;
typedef unsigned long xmlrpc_timeout;
/* A timeout in milliseconds. */
typedef void (*xmlrpc_transport_finish_asynch)(
struct xmlrpc_client_transport * const clientTransportP,
xmlrpc_timeoutType const timeoutType,
xmlrpc_timeout const timeout);
struct xmlrpc_client_transport_ops {
xmlrpc_transport_create create;
xmlrpc_transport_destroy destroy;
xmlrpc_transport_send_request send_request;
xmlrpc_transport_call call;
xmlrpc_transport_finish_asynch finish_asynch;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,42 @@
/* Copyright information is at the end of the file */
#ifndef XMLRPC_TRANSPORT_INT_H_INCLUDED
#define XMLRPC_TRANSPORT_INT_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "pthreadx.h" /* For threading helpers. */
/*=========================================================================
** Transport Helper Functions and declarations.
**=========================================================================
*/
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);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,30 @@
#ifndef XML_HPP_INCLUDED
#define XML_HPP_INCLUDED
#include <string>
#include <xmlrpc-c/base.hpp>
namespace xmlrpc_c {
namespace xml {
void
generateCall(std::string const& methodName,
xmlrpc_c::paramList const& paramList,
std::string * const callXmlP);
void
parseSuccessfulResponse(std::string const& responseXml,
xmlrpc_c::value * const resultP);
void
parseResponse(std::string const& responseXml,
xmlrpc_c::rpcOutcome * const outcomeP);
void
trace(std::string const& label,
std::string const& xml);
}} // namespace
#endif

View File

@@ -0,0 +1,89 @@
/* Copyright and license information is at the end of the file */
#ifndef XMLRPC_XMLPARSER_H_INCLUDED
#define XMLRPC_XMLPARSER_H_INCLUDED
/*=========================================================================
** 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);
/* 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